基于Angularjs+jasmine+karma的测试驱动开发(TDD)实例
簡介(摘自baidu)
測試驅動開發,英文全稱Test-Driven Development,簡稱TDD,是一種不同于傳統軟件開發流程的新型的開發方法。它要求在編寫某個功能的代碼之前先編寫測試代碼,然后只編寫使測試通過的功能代碼,通過測試來推動整個開發的進行。這有助于編寫簡潔可用和高質量的代碼,并加速開發過程。
?
優勢
?
流程
?
類庫/工具介紹
angularjs 1.X: 依賴注入,MVC架構,使代碼可測試
karma: 測試工具
jasmine: 測試框架
?
實例
多選
功能描述
按住ctrl,shift時將多選項目,因右鍵菜單的不同,isEdit=true的項,將顯示菜單1,isEdit=false的項將顯示菜單2,isEdit不同的項不能被一起選中,某些項標注為opEnable為false的表示不能被操作,便不能被選中,切換tab時,當前所有選中的項將失效。
?
定義測試用例
?
定義測試數據:
ABCD為isEdit=true
EFGH為isEdit=false
IJKL為isEdit=true
?
A的opEnable = false
F的opEnable=false
?
測試用例偽代碼
Ctrl
?
Shift
按住shift的多選將由起始項開始選到當前點擊項
起始項定為最后一次選中的項
?
起始項的測試
?
shift的測試
?
右鍵菜單
功能描述
右鍵項目時,存在目標項,為之后右鍵菜單中需要操作的目標,相應的菜單項會因目標不同而改變,目標項即右鍵時點中的項,如點中項在多選狀態時,則目標項為所有被選中的項,如右鍵點中得項處于未選中狀態時,則目標項為右鍵點中的項。如右鍵點中的項opEnable為false,則不彈出右鍵菜單。
測試用例偽代碼
定義右鍵isEdit=true時,菜單為1,定義右鍵isEdit=false時菜單為2
?
定義測試數據
ABCD為isEdit=true
EFGH為isEdit=false
IJKL為isEdit=true
?
A的opEnable = false
F的opEnable=false
?
代碼如下
測試用例 + 代碼實現
1. 按住ctrl點擊B,B選中
測試用例代碼
1 it('should set B selected if ctrlClick on B', function () { 2 expect(B.selected).toBeFalsy(); 3 $scope.ctrlClick(B); 4 expect(B.selected).toBeTruthy(); 5 });測試報錯,ctrlClick函數未定義
實現邏輯
?
測試通過
?
2. 按住ctrl點擊B,B選中, 再次點擊B,B未選中
測試用例代碼
1 it('should set B unselected if ctrlClick on selected B', function () { 2 expect(B.selected).toBeFalsy(); 3 $scope.ctrlClick(B); 4 expect(B.selected).toBeTruthy(); 5 $scope.ctrlClick(B); 6 expect(B.selected).toBeFalsy(); 7 });測試失敗,修改代碼
?
測試通過
?
3. 按住ctrl點擊B,B選中,點擊C,C選中,點擊D,D選中
測試用例代碼:
1 it('should set BCD selected if ctrlClick on B,C,D', function () { 2 expect(B.selected).toBeFalsy(); 3 expect(C.selected).toBeFalsy(); 4 expect(D.selected).toBeFalsy(); 5 $scope.ctrlClick(B); 6 expect(B.selected).toBeTruthy(); 7 $scope.ctrlClick(C); 8 expect(C.selected).toBeTruthy(); 9 $scope.ctrlClick(D); 10 expect(D.selected).toBeTruthy(); 11 });測試通過
?
4. 按住ctrl點擊B,B選中,點擊C,C選中,點擊D,D選中,點擊E, 取消BCD的選中狀態,只選中E
測試用例代碼
1 it('should set BCD unselected if ctrlClick on E', function () { 2 expect(B.selected).toBeFalsy(); 3 expect(C.selected).toBeFalsy(); 4 expect(D.selected).toBeFalsy(); 5 $scope.ctrlClick(B); 6 expect(B.selected).toBeTruthy(); 7 $scope.ctrlClick(C); 8 expect(C.selected).toBeTruthy(); 9 $scope.ctrlClick(D); 10 expect(D.selected).toBeTruthy(); 11 $scope.ctrlClick(E); 12 expect(E.selected).toBeTruthy(); 13 expect(B.selected).toBeFalsy(); 14 expect(C.selected).toBeFalsy(); 15 expect(D.selected).toBeFalsy(); 16 });測試失敗,修改代碼
測試通過
?
5. 按住ctrl點擊B,B選中,點擊C,C選中,點擊D,D選中,切換Tab,取消BCD的選中狀態
測試用例代碼
1 it('should set BCD unselected if change the tab', function () { 2 expect(B.selected).toBeFalsy(); 3 expect(C.selected).toBeFalsy(); 4 expect(D.selected).toBeFalsy(); 5 $scope.ctrlClick(B); 6 expect(B.selected).toBeTruthy(); 7 $scope.ctrlClick(C); 8 expect(C.selected).toBeTruthy(); 9 $scope.ctrlClick(D); 10 expect(D.selected).toBeTruthy(); 11 $scope.selectTab("A-Shares"); 12 expect(B.selected).toBeFalsy(); 13 expect(C.selected).toBeFalsy(); 14 expect(D.selected).toBeFalsy(); 15 });測試失敗,修改代碼
?
在原先的切換tab方法中增加了resetSelected的方法調用。
測試通過
?
6. 按住ctrl點擊A,不能選中A
測試用例代碼
1 it('should set A unselected if ctrlClick on A', function () { 2 expect(A.selected).toBeFalsy(); 3 $scope.ctrlClick(A); 4 expect(A.selected).toBeFalsy(); 5 });測試失敗,修改代碼
?
測試通過
?
7. 按住ctrl分別點擊B, C,D,選中項為BCD,再點擊A,選中項還是只有BCD
測試用例代碼
1 it('should set A unselected if ctrlClick on A', function () { 2 expect(A.selected).toBeFalsy(); 3 expect(B.selected).toBeFalsy(); 4 expect(C.selected).toBeFalsy(); 5 expect(D.selected).toBeFalsy(); 6 $scope.ctrlClick(B); 7 $scope.ctrlClick(C); 8 $scope.ctrlClick(D); 9 expect(B.selected).toBeTruthy(); 10 expect(C.selected).toBeTruthy(); 11 expect(D.selected).toBeTruthy(); 12 $scope.ctrlClick(A); 13 expect(B.selected).toBeTruthy(); 14 expect(C.selected).toBeTruthy(); 15 expect(D.selected).toBeTruthy(); 16 expect(A.selected).toBeFalsy(); 17 });測試通過
?
8. 按住ctrl點擊B, 初始項為B
測試用例代碼
1 it('should set B index if ctrlClick on B', function () { 2 expect(B.selected).toBeFalsy(); 3 $scope.ctrlClick(B); 4 expect(B.selected).toBeTruthy(); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 });測試失敗,修改代碼
?
測試通過
?
9. 按住shift點擊B,起始項為B
測試用例代碼
1 it('should set B index if shiftClick on B', function () { 2 $scope.shiftClick(B); 3 expect($scope.startIndex).toEqual(B.nodeIndex); 4 });?測試失敗,修改代碼
?
測試通過
?
10. 按住ctrl點擊B,再選中C 再不選中C,起始項為B
測試用例代碼
1 it('should set B index if ctrlClick on B, then set C index if ctrlClick on C', function () { 2 $scope.ctrlClick(B); 3 expect($scope.startIndex).toEqual(B.nodeIndex); 4 $scope.ctrlClick(C); 5 expect($scope.startIndex).toEqual(C.nodeIndex); 6 });測試通過
?
11. 按住ctrl點擊B,再不選中B,起始項為-1
測試用例代碼
1 it('should set B index if ctrlClick on B, unselected B will change the index to -1', function () { 2 expect(B.selected).toBeFalsy(); 3 $scope.ctrlClick(B); 4 expect(B.selected).toBeTruthy(); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 $scope.ctrlClick(B); 7 expect(B.selected).toBeFalsy(); 8 expect($scope.startIndex).toEqual(-1); 9 });測試失敗,修改代碼
?
測試通過
?
12. 按住ctrl點擊B,起始項為B,再選中C,起始項為C,不選中C,起始項為B,再不選中B,起始項為-1
測試用例代碼
1 it('should have a selectIndex list', function () { 2 expect(B.selected).toBeFalsy(); 3 expect(C.selected).toBeFalsy(); 4 $scope.ctrlClick(B); 5 expect(B.selected).toBeTruthy(); 6 expect($scope.startIndex).toEqual(B.nodeIndex); 7 $scope.ctrlClick(C); 8 expect(C.selected).toBeTruthy(); 9 expect($scope.startIndex).toEqual(C.nodeIndex); 10 $scope.ctrlClick(C); 11 expect(C.selected).toBeFalsy(); 12 expect($scope.startIndex).toEqual(B.nodeIndex); 13 $scope.ctrlClick(B); 14 expect(B.selected).toBeFalsy(); 15 expect($scope.startIndex).toEqual(-1); 16 });測試不通過,修改代碼
測試通過,提取函數,重構代碼
?
測試通過
?
13. 按住ctrl點擊B,起始項為B,再選中C,起始項為C,再選中D,起始項為D,不選中C,起始項為D,再不選中D,起始項為B,再不選中B,起始項為-1
測試用例代碼
1 it('should have a selectIndex list 2', function () { 2 $scope.ctrlClick(B); 3 expect($scope.startIndex).toEqual(B.nodeIndex); 4 $scope.ctrlClick(C); 5 expect($scope.startIndex).toEqual(C.nodeIndex); 6 $scope.ctrlClick(D); 7 expect($scope.startIndex).toEqual(D.nodeIndex); 8 $scope.ctrlClick(C); 9 expect($scope.startIndex).toEqual(D.nodeIndex); 10 $scope.ctrlClick(D); 11 expect($scope.startIndex).toEqual(B.nodeIndex); 12 $scope.ctrlClick(B); 13 expect($scope.startIndex).toEqual(-1); 14 });測試通過
?
14. 按住ctrl點擊A,初始項為-1
測試用例代碼
1 it('should remain index to -1 if ctrlClick on A', function () { 2 expect($scope.startIndex).toEqual(-1); 3 expect(A.selected).toBeFalsy(); 4 $scope.ctrlClick(A); 5 expect(A.selected).toBeFalsy(); 6 expect($scope.startIndex).toEqual(-1); 7 });測試通過
?
15. 按住ctrl點擊B,初始項為B, ctrl點擊A,初始項還是B
測試用例代碼
1 it('should remain index to currentIndex if ctrlClick on A', function () { 2 $scope.ctrlClick(B); 3 expect($scope.startIndex).toEqual(B.nodeIndex); 4 $scope.ctrlClick(A); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 });測試通過
?
16. 初始項為-1,按住shift點擊B, B選中,初始項為B
測試用例代碼
1 it('should set B index if shiftClick on B', function () { 2 expect(B.selected).toBeFalsy(); 3 $scope.shiftClick(B); 4 expect(B.selected).toBeTruthy(); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 });測試失敗,修改代碼
?
測試通過
?
17. 初始項為B,按住shift點擊B,不取消B的選中狀態
測試用例代碼
1 it('should still set B index if shiftClick on B twice', function () { 2 expect(B.selected).toBeFalsy(); 3 $scope.shiftClick(B); 4 expect(B.selected).toBeTruthy(); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 $scope.shiftClick(B); 7 expect(B.selected).toBeTruthy(); 8 expect($scope.startIndex).toEqual(B.nodeIndex); 9 });測試通過
?
18. 初始項為B,按住shift選D,將選中BCD
測試用例代碼
1 it('should set BCD selected if shiftClick on B then D', function () { 2 $scope.shiftClick(B); 3 expect(B.selected).toBeTruthy(); 4 $scope.shiftClick(D); 5 expect(B.selected).toBeTruthy(); 6 expect(C.selected).toBeTruthy(); 7 expect(D.selected).toBeTruthy(); 8 });測試失敗,修改代碼
?
測試通過
?
19. 初始項為D,按住shift選B,將選中BCD
測試用例代碼
1 it('should set BCD selected if shiftClick on D then B', function () { 2 $scope.shiftClick(D); 3 expect(D.selected).toBeTruthy(); 4 $scope.shiftClick(B); 5 expect(B.selected).toBeTruthy(); 6 expect(C.selected).toBeTruthy(); 7 expect(D.selected).toBeTruthy(); 8 });測試通過
?
20. 初始項為B,按住shift選C,將選中BC,按住ctrl點擊D, 將選中BCD,shift選A,將選中BCD
測試用例代碼
1 it('should set BCD selected if shiftClick on B,C,ctrlClick on D, shift A', function () { 2 $scope.shiftClick(B); 3 expect(B.selected).toBeTruthy(); 4 $scope.shiftClick(C); 5 expect(B.selected).toBeTruthy(); 6 expect(C.selected).toBeTruthy(); 7 $scope.ctrlClick(D); 8 expect(B.selected).toBeTruthy(); 9 expect(C.selected).toBeTruthy(); 10 expect(D.selected).toBeTruthy(); 11 $scope.shiftClick(A); 12 expect(A.selected).toBeFalsy(); 13 expect(B.selected).toBeTruthy(); 14 expect(C.selected).toBeTruthy(); 15 expect(D.selected).toBeTruthy(); 16 });測試失敗,修改代碼
?
測試通過
?
21. 初始項為B,按shift選D,初始項為D, ctrl點擊D,取消D,初始項變為C,ctrl點擊C,取消C,初始項變為B, ctrl點擊B,初始項變-1
測試用例代碼
1 it('should set correct index when use shiftClick', function () { 2 expect($scope.startIndex).toEqual(-1); 3 $scope.shiftClick(B); 4 expect($scope.startIndex).toEqual(B.nodeIndex); 5 $scope.shiftClick(D); 6 expect($scope.startIndex).toEqual(D.nodeIndex); 7 $scope.ctrlClick(D); 8 expect($scope.startIndex).toEqual(C.nodeIndex); 9 $scope.ctrlClick(C); 10 expect($scope.startIndex).toEqual(B.nodeIndex); 11 $scope.ctrlClick(B); 12 expect($scope.startIndex).toEqual(-1); 13 });測試失敗,修改代碼
?
測試通過
?
22. 初始項為D,按shift選B,初始項為B, ctrl點擊B,取消B,初始項變為C,ctrl點擊C,取消C,初始項變為D, ctrl點擊D,初始項變-1
測試用例代碼
1 it('should set correct index when use shiftClick reverse', function () { 2 expect($scope.startIndex).toEqual(-1); 3 $scope.shiftClick(D); 4 expect($scope.startIndex).toEqual(D.nodeIndex); 5 $scope.shiftClick(B); 6 expect($scope.startIndex).toEqual(B.nodeIndex); 7 $scope.ctrlClick(B); 8 expect($scope.startIndex).toEqual(C.nodeIndex); 9 $scope.ctrlClick(C); 10 expect($scope.startIndex).toEqual(D.nodeIndex); 11 $scope.ctrlClick(D); 12 expect($scope.startIndex).toEqual(-1); 13 });測試通過
?
23. 初始項為B,shift點擊E,則取消B,只選中E,初始項相應的變為E,Ctrl點擊E,E不選中,初始項變-1
測試用例代碼
1 it('should not select different isEdit status while using shiftClick', function () { 2 expect($scope.startIndex).toEqual(-1); 3 $scope.shiftClick(B); 4 expect(B.selected).toBeTruthy(); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 $scope.shiftClick(E); 7 expect(B.selected).toBeFalsy(); 8 expect(E.selected).toBeTruthy(); 9 expect($scope.startIndex).toEqual(E.nodeIndex); 10 $scope.ctrlClick(E); 11 expect(B.selected).toBeFalsy(); 12 expect(E.selected).toBeFalsy(); 13 expect($scope.startIndex).toEqual(-1); 14 });測試失敗,修改代碼
?
測試通過,重構代碼
測試通過
24. 初始項為B,shift點擊I,將取消B,只選中I,初始項變為I
測試用例代碼
1 it('should not select different isEdit status while using shiftClick 2', function () { 2 expect($scope.startIndex).toEqual(-1); 3 $scope.shiftClick(B); 4 expect(B.selected).toBeTruthy(); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 $scope.shiftClick(I); 7 expect(B.selected).toBeFalsy(); 8 expect(I.selected).toBeTruthy(); 9 expect($scope.startIndex).toEqual(I.nodeIndex); 10 expect(_.where($scope.allNodes, { selected: true}).length).toEqual(1); 11 });測試通過
?
25. shift點擊E,shift點擊H,將選中EGH,F未選中
測試用例代碼
1 it('should skip the opEnable=false item', function () { 2 $scope.shiftClick(E); 3 expect(E.selected).toBeTruthy(); 4 expect($scope.startIndex).toEqual(E.nodeIndex); 5 $scope.shiftClick(H); 6 expect(E.selected).toBeTruthy(); 7 expect(F.selected).toBeFalsy(); 8 expect(G.selected).toBeTruthy(); 9 expect(H.selected).toBeTruthy(); 10 expect($scope.startIndex).toEqual(H.nodeIndex); 11 expect(_.where($scope.allNodes, { selected: true}).length).toEqual(3); 12 });測試失敗,修改代碼
?
測試通過
?
26. shift點擊E,shift點擊H,將選中EGH,F未選中,初始項為H, ctrl點擊H, 取消H的選中狀態,初始項變為G,ctrl點擊G,取消G的選中狀態,初始項變為E
測試用例代碼
1 it('should have right index when skipped the opEnable=false item', function () { 2 $scope.shiftClick(E); 3 expect(E.selected).toBeTruthy(); 4 expect($scope.startIndex).toEqual(E.nodeIndex); 5 $scope.shiftClick(H); 6 expect(E.selected).toBeTruthy(); 7 expect(F.selected).toBeFalsy(); 8 expect(G.selected).toBeTruthy(); 9 expect(H.selected).toBeTruthy(); 10 expect($scope.startIndex).toEqual(H.nodeIndex); 11 expect(_.where($scope.allNodes, { selected: true}).length).toEqual(3); 12 13 $scope.ctrlClick(H); 14 expect(H.selected).toBeFalsy(); 15 expect($scope.startIndex).toEqual(G.nodeIndex); 16 $scope.ctrlClick(G); 17 expect(G.selected).toBeFalsy(); 18 expect($scope.startIndex).toEqual(E.nodeIndex); 19 });測試通過
?
27. 若選中了BCD,切換tab,將設置回初始項為-1,取消BCD的選中狀態
測試用例代碼
1 it('should clear the shift selection when change the tab', function () { 2 $scope.shiftClick(B); 3 expect(B.selected).toBeTruthy(); 4 $scope.shiftClick(D); 5 expect(B.selected).toBeTruthy(); 6 expect(C.selected).toBeTruthy(); 7 expect(D.selected).toBeTruthy(); 8 $scope.selectTab("A-Shares"); 9 expect(B.selected).toBeFalsy(); 10 expect(C.selected).toBeFalsy(); 11 expect(D.selected).toBeFalsy(); 12 });測試通過
?
28. 初始項為-1,shift點擊A,不選中A,初始項為-1
測試用例代碼
1 it('should remain the index -1 when shiftClick A', function () { 2 expect($scope.startIndex).toEqual(-1); 3 $scope.shiftClick(A); 4 expect($scope.startIndex).toEqual(-1); 5 });測試通過
?
29. shift選擇B,再shift選擇D,將選中BCD,初始項變為D,若shift點擊A,則不會改變選中的BCD,初始項還是D
測試用例代碼
1 it('should remain currentIndex when shiftClick A', function () { 2 expect($scope.startIndex).toEqual(-1); 3 $scope.shiftClick(B); 4 expect(B.selected).toBeTruthy(); 5 expect($scope.startIndex).toEqual(B.nodeIndex); 6 $scope.shiftClick(D); 7 expect(B.selected).toBeTruthy(); 8 expect(C.selected).toBeTruthy(); 9 expect(D.selected).toBeTruthy(); 10 expect($scope.startIndex).toEqual(D.nodeIndex); 11 $scope.shiftClick(A); 12 expect($scope.startIndex).toEqual(D.nodeIndex); 13 });測試通過
?
30. 右鍵A,不彈出菜單
測試用例代碼
1 it('should show no menu when rightClick A', function () { 2 $scope.rightClick(A); 3 expect($rootScope.contextMenuStatus.isShow).toBeFalsy(); 4 });測試失敗,修改代碼
?
測試通過
?
31. 右鍵B,彈出菜單1,目標項為B
測試用例代碼
1 it('should show menu 1 when rightClick B', function () { 2 $scope.rightClick(B); 3 expect($rootScope.contextMenuStatus.isShow).toBeTruthy(); 4 expect($rootScope.contextMenuStatus.menuCode).toEqual(1); 5 expect($scope.targetNodes[0]).toBe(B); 6 });測試失敗,修改代碼
?
測試通過
?
32. 右鍵E,彈出菜單2,目標項為E
測試用例代碼
1 it('should show menu 2 when rightClick E', function () { 2 $scope.rightClick(E); 3 expect($rootScope.contextMenuStatus.isShow).toBeTruthy(); 4 expect($rootScope.contextMenuStatus.menuCode).toEqual(2); 5 expect($scope.targetNodes[0]).toBe(E); 6 });測試通過
?
33. Ctrl點擊BCD,右鍵B,彈出菜單1,目標項為BCD
測試用例代碼
1 it('should show menu 1 and target is BCD when rightClick BCD', function () { 2 $scope.shiftClick(B); 3 $scope.shiftClick(D); 4 $scope.rightClick(B); 5 expect($rootScope.contextMenuStatus.isShow).toBeTruthy(); 6 expect($rootScope.contextMenuStatus.menuCode).toEqual(1); 7 expect($scope.targetNodes.length).toEqual(3); 8 expect($scope.targetNodes[0]).toBe(B); 9 expect($scope.targetNodes[1]).toBe(C); 10 expect($scope.targetNodes[2]).toBe(D); 11 });測試失敗,修改代碼
?
測試通過
?
34. Ctrl點擊BCD,右鍵E,彈出菜單2,目標項為E
測試用例代碼
1 it('should show menu 2 when rightClick E even if BCD is selected', function () { 2 $scope.shiftClick(B); 3 $scope.shiftClick(D); 4 $scope.rightClick(E); 5 expect($rootScope.contextMenuStatus.isShow).toBeTruthy(); 6 expect($rootScope.contextMenuStatus.menuCode).toEqual(2); 7 expect($scope.targetNodes[0]).toBe(E); 8 });測試通過
?
35. Ctrl點擊BCD,右鍵A,不彈出菜單
測試用例代碼
1 it('should show no menu when rightClick A even if BCD is selected', function () { 2 $scope.shiftClick(B); 3 $scope.shiftClick(D); 4 $scope.rightClick(A); 5 expect($rootScope.contextMenuStatus.isShow).toBeFalsy(); 6 });測試通過
轉載于:https://www.cnblogs.com/nickppa/p/5406600.html
總結
以上是生活随笔為你收集整理的基于Angularjs+jasmine+karma的测试驱动开发(TDD)实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (计算机组成原理)第二章数据的表示和运算
- 下一篇: 二叉树经典题之根据二叉树创建字符串(二叉