TDD實作三大策略
Kent 在Test Driven Development by example一書中, 提到了在使用TDD方法來開發程式時, 有三個策略你可以使用:
1. Faking it
- 先用hard code的方式讓程式可以快速通過測試.
- 我們的目標是讓測試快點通過, 先有些進展, 然後再調整和優化程式.
2. Use Obvious Implementation
- 使用真正的實作, 或是顯而易見的實作方式
- 每次前進一小步
3. Triangulation (三角定位法)
- 有時候只從一個面向看問題會不準確, 因此若是能從多個面向來思考這個問題, 我們會得到更正確的結果
- 同理test case也是. 只有某一種test case可能導致你hard code某些狀況. 若是能有多類不同狀況的test case, 可以幫助我們寫出更好的程式.
Kent在書中有個費式數列的範例. 我們可以用它來對照這三個策略:
1. 第0個的值是0
public void testFibonacci() {
assertEquaks(0, fib(0));
}
2. 利用faking it的方式, 先hard code, 來通過測試
int fib(int n) {
return 0;
}
3. 再加一個測試
public void testFibonacci() {
assertEquals(0, fib(0));
assertEquals(1, fib(1));
}
4. 我們再利用faking it, 來通過測試
int fib(int n) {
if (n==0) return 0;
return 1;
}
5. 我們加更多的測試, 可是仍然無法原先的實作, 因為原先的實作不用修改就可以通過測試
public void testFibonacci() {
int cases[][] = {{0,0}, {1,1}, {2,1}}
for (int i = 0; I
assertEquals( cases[i][1], fib(case[i],[0]));
}
6. 這代表我們的面向不夠有代表性, 仍然定位不出我們要的實作. 所以我們再加一個測試. (Triangulation)
public void testFibonacci() {
int cases[][] = {{0,0}, {1,1}, {2,1}, {3,2}}
for (int i = 0; I
assertEquals( cases[i][1], fib(case[i],[0]));
}
7. 這時測試已經有足夠的代表性, 我們需要修改我們的實作
(1) 小修改, 還是faking it的招數
int fib(int n) {
if (n==0) return 0;
if (n
return 2; (2 其實代表 1 + 1)
}
(2) 但是我們知道費數數列的公式, 因此我們可以用Obvious Implementation, 以最簡單的方式來實作
int fib(int n) {
if (n==0) return 0;
if (n==1) return 1;
return fib(n-1)+ fib(n-2);
}