從零基礎認識TDD開發

TDD的Demo

M:什麼是TDD?

Z:TDD是測試驅動開發(Test-Driven Development)的英文簡稱,是敏捷開發中的一項核心實踐和技術,也是一種設計方法論。TDD的原理是在開發功能代碼之前,先編寫單元測試用例代碼,測試代碼確定需要編寫什麼產品代碼。

M:那具體要怎麼做呢?

Z: 如下

這裏寫圖片描述

M:能寫一個Demo麼?

Z:TDD開發Demo:測試會返回所有素數數組的方法(邊界版)

  1. 測試案例可能有哪些:邊界數據 , 正常數據

    邊界數據:0,-1,2

    正常數據:9,17,30

    創建測試用例:測試邊界條件

    @Test
    public void testGetPrimesForEmptyResult() {
        int[] expected = {};
    
        Assert.assertArrayEquals(expected, PrimeUtil.getPrimes(2));
        Assert.assertArrayEquals(expected, PrimeUtil.getPrimes(0));
        Assert.assertArrayEquals(expected, PrimeUtil.getPrimes(-1));
    }
  2. 運行失敗嘗試:寫一個有問題的測試對象,保證案例具有判斷能力

    public class PrimeUtil {
    public static int[] getPrimes(int i){
    
        return null;
    }
    }
  3. 編寫功能代碼,通過測試案例

    public static int[] getPrimes(int max){
        if(max <= 2){
            return new int[]{};
        }
        return null;
    }
  4. 重構,這裏代碼很簡潔,無需再進行重構。

Z:TDD開發Demo:測試會返回所有素數數組的方法(正常版)

  1. 編寫測試案例:

    @Test
    public void testGetPrimes(){
    
        Assert.assertArrayEquals(new int[]{2,3,5,7}, PrimeUtil.getPrimes(9));
        Assert.assertArrayEquals(new int[]{2,3,5,7,11,13}, PrimeUtil.getPrimes(17));
        Assert.assertArrayEquals(new int[]{2,3,5,7,11,13,17,19,23,29}, PrimeUtil.getPrimes(30));
    }
  2. 運行失敗嘗試,沒有代碼,返回失敗

  3. 編寫功能代碼,通過測試案例

    public static int[] getPrimes(int max){
        if(max <= 2){
            return new int[]{};
        }else{
            int[] newArray = new int[max];
            int size = 0;
            int j = 0;
            for(int i=2 ; i < max ; i++){
                for (j = 2; j < i/2+1; j++) {
                    if(i % j == 0){
                        break;
                    }
                }
                if(j == i/2+1){
                    newArray[size++] = i;
                }
            }
            newArray = Arrays.copyOf(newArray, size);
            return newArray;
        }
    }
  4. 重構,雖然這段代碼通過了測試案例,但是其編寫很複雜,可以重構如下:

    • 重命名(無需測試)
    public static int[] getPrimes(int max){
        if(max <= 2){
            return new int[]{};
        }else{
            int[] primes = new int[max];
            int count = 0;
            int j = 0;
            for(int num=2 ; num < max ; num++){
                for (j = 2; j < num/2+1; j++) {
                    if(num % j == 0){
                        break;
                    }
                }
                if(j == num/2+1){
                    primes[count++] = num;
                }
            }
            primes = Arrays.copyOf(primes, count);
            return primes;
        }
    }
    • 提取函數(測試)
    public static int[] getPrimes(int max){
        if(max <= 2){
            return new int[]{};
        }else{
            int[] primes = new int[max];
            int count = 0;
            for(int num=2 ; num < max ; num++){
                if(isPrime(num)){
                    primes[count++] = num;
                }
            }
            primes = Arrays.copyOf(primes, count);
            return primes;
        }
    }
    
    private static boolean isPrime(int num) {
        for (int j = 2; j < num/2+1; j++) {
            if(num % j == 0){
                return false;
            }
        }
        return true;
    }
    • 分支進行調整(測試)
    public static int[] getPrimes(int max){
        if(max <= 2){
            return new int[]{};
        }
        int[] primes = new int[max];
        int count = 0;
        for(int num=2 ; num < max ; num++){
            if(isPrime(num)){
                primes[count++] = num;
            }
        }
        primes = Arrays.copyOf(primes, count);
        return primes;
    }
    
    private static boolean isPrime(int num) {
        for (int i = 2; i < num/2+1; i++) {
            if(num % i == 0){
                return false;
            }
        }
        return true;
    }

M:到這裏,邊界條件和正常輸入的測試用例就都通過了。總結一下,TDD開發方式:

  1. 分析,編寫不同方面的測試用例
  2. 每個測試用例之前先確保Junit具有報錯能力,做個錯誤的返回測試
  3. 編寫實現代碼
  4. 對代碼進行重構:先重構名稱,提取方法,修改結構
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章