Driven By Test…
程啟健(Kelvin)
前兩天Eric說搞個(gè)讀書協(xié)會(huì),那就讓我來寫第一篇吧。第一篇是關(guān)于Test-Driven Development的。
TDD(Test-Driven Development)顧名思義就是測(cè)試驅(qū)動(dòng)的開發(fā)。以測(cè)試驅(qū)動(dòng)并不是代表以測(cè)試人員為中心進(jìn)行開發(fā),而是把要測(cè)試的內(nèi)容作為軟件開發(fā)的目標(biāo)來開發(fā)。測(cè)試的Case就是我們要達(dá)到的目標(biāo)。其原則如下:
TDD和Refactoring成為XP中最重要的實(shí)踐。兩者相輔相成,重構(gòu)就是不改變程序內(nèi)在功能的前提下更改代碼的結(jié)構(gòu)。測(cè)試才能驗(yàn)證你的重構(gòu)沒有改變其功能。
TDD的具體流程是怎樣的呢?為何測(cè)試可以在編碼先呢?
以下是簡(jiǎn)單的TDD的Sample(摘自TDD a practical guide by David Astels):
本Sample假設(shè)你已了解JUnit等測(cè)試軟件。
GOAL:做個(gè)電影的平均評(píng)分的函數(shù)。給個(gè)例子,假如觀眾甲給3分,觀眾乙給5分,平均分為4分。
1.把目標(biāo)做成測(cè)試用例。
public void testRating() {
assertEquals("Bad average rating.",4,starWars.getAverageRating());
}
Make it Simple。就讓平均評(píng)分為4分先吧。
2.但是總不能都是4分,而且評(píng)分的人可是觀眾阿。加個(gè)添加評(píng)分的函數(shù)。
public void testRating() {
starWars.addRating(3);
starWars.addRating(5);
assertEquals("Bad average rating.",4,starWars.getAverageRating());
}
3.什么電影呢?是星球大戰(zhàn)!
public void testRating() {
Movie starWars = new Movie("Star Wars");
starWars.addRating(3);
starWars.addRating(5);
assertEquals("Bad average rating.",4,starWars.getAverageRating());
}
4.編譯這些代碼的時(shí)候發(fā)現(xiàn)addRating(int)和getAverageRating()沒有定義。趕緊在Movie類中寫這些函數(shù)。
public void addRating(int newRating) {
}
public int getAverageRating() {
return 0;
}
測(cè)試失敗?Bad average rating. expected:<4> but was:<0>
5.應(yīng)該返回4而不是0!那就返回4吧。
public int getAverageRating() {
return 4;
}
重新編譯,綠條出現(xiàn)。Yeah。下面我們進(jìn)入重構(gòu)階段了。
6.評(píng)分是由3分+5分的和后除以2才得的。直接返回4不符合要求阿。改。
public int getAverageRating() {
return (3 + 5) / 2;
}
7.編譯成功。又出綠條。但是算法上應(yīng)該是總分除以個(gè)數(shù)才可以阿。繼續(xù)該吧。
private int totalRating = 0;
private int numberOfRatings = 0;
public void addRating(int newRating) {
totalRating += newRating;
numberOfRatings++;
}
public int getAverageRating() {
return totalRating / numberOfRatings;
}
8.編譯運(yùn)行。綠色的.yeah.成功。寫多些用例測(cè)試下。大家來評(píng)評(píng)《哥斯拉》這部電影。
public void testLotsOfRatings()
{
Moviegodzilla = new Movie("Godzilla");
godzilla.addRating(1);
godzilla.addRating(5);
godzilla.addRating(1);
godzilla.addRating(2);
assertEquals("Bad average rating.",2,godzilla.getAverageRating());
}
TDD就是這樣一個(gè)編寫測(cè)試、編寫代碼、再測(cè)試、重構(gòu)、再測(cè)試的過程。實(shí)現(xiàn)盡量少的功能,不斷地對(duì)代碼進(jìn)行重構(gòu)。利用TDD開發(fā)出來的代碼將會(huì)更干凈、更安全、更易于重構(gòu)的。