TDD的Demo
M:什麼是TDD?
Z:TDD是測試驅動開發(Test-Driven Development)的英文簡稱,是敏捷開發中的一項核心實踐和技術,也是一種設計方法論。TDD的原理是在開發功能代碼之前,先編寫單元測試用例代碼,測試代碼確定需要編寫什麼產品代碼。
M:那具體要怎麼做呢?
Z: 如下
M:能寫一個Demo麼?
Z:TDD開發Demo:測試會返回所有素數數組的方法(邊界版)
測試案例可能有哪些:邊界數據 , 正常數據
邊界數據: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)); }
運行失敗嘗試:寫一個有問題的測試對象,保證案例具有判斷能力
public class PrimeUtil { public static int[] getPrimes(int i){ return null; } }
編寫功能代碼,通過測試案例
public static int[] getPrimes(int max){ if(max <= 2){ return new int[]{}; } return null; }
重構,這裏代碼很簡潔,無需再進行重構。
Z:TDD開發Demo:測試會返回所有素數數組的方法(正常版)
編寫測試案例:
@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)); }
運行失敗嘗試,沒有代碼,返回失敗
編寫功能代碼,通過測試案例
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; } }
重構,雖然這段代碼通過了測試案例,但是其編寫很複雜,可以重構如下:
- 重命名(無需測試)
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開發方式:
- 分析,編寫不同方面的測試用例
- 每個測試用例之前先確保Junit具有報錯能力,做個錯誤的返回測試
- 編寫實現代碼
- 對代碼進行重構:先重構名稱,提取方法,修改結構