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 < cases.length; 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 < cases.length; i++)
        assertEquals( cases[i][1], fib(case[i],[0]));
}

7. 這時測試已經有足夠的代表性, 我們需要修改我們的實作
(1) 小修改, 還是faking it的招數
int fib(int n) {
    if (n==0) return 0;
    if (n<=2) return 1;
    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);
}


全站熱搜

kojenchieh 發表在 痞客邦 留言(0) 人氣()