作者:Keld H. Hansen 翻譯:CManLH 原文地址
一、介紹
二、進入junit的天堂
三、Round類
四、分析並擷取測試案例
測試是件非常容易犯困的工作。測試他人寫的程式時,感覺更加誇張。如果你同樣為一名開發人員,那可能就升級為一種煎熬。作為開發人員,我們天生熱衷於創造。但轉念想想,為什麼不自己創造一個程式來測試其它程式甚至其本身呢?誕生於自動化測試後的這種思想,正是本文主題所在。
自動化單元測試(一般來說,一個類為一個單元)其實並不是件新鮮事。多年前我們應用於大型主機的一些測試方法,站在自動化單元測試的角度,它們依然有效。自動化單元測試與隨機測試有著以下的不同:
一、使得在程式修改後,只對進行修改的部分重新測試的工作(常被稱為“迴歸測試”),變得非常容易。
二、擁有一個強大的測試構架,當你編譯代碼或者布署應用時,能自動進行實際有效測試。
正確的使用單元測試,可以協助我們提高編寫程式的效率,同時提升代碼的品質。只有當確信單元測試是程式編寫過程中重要的環節,才會被促使去設計經得起測試的代碼。實際上,將注意力集中在介面與類所要實現的行為上,先編寫測試代碼,然後才編寫程式碼,已經成為當今的趨勢。不過,本文皆在簡單地展示單元測試,所以被用來測試的代碼實際是已經存在的。
高爾夫運動
想以生活中的一個小例子來描述自動化測試的整個過程。所以,讓我們打會兒高爾夫吧!案例為:我們需要編寫一個程式來記錄一場高爾夫的分數。聰明過人的你,很快知道需要以下兩個類:
1、球場(Course)-有以下屬性:球場名稱;每個洞的標準杆數
2、一場球(Round)(每一位球手的得分)-有以下屬性:球手的名稱(球手其實可以作為一個對象,但為了簡單,故沒有那樣做);球場;各個洞的杆數
我們一定都想清楚地知道球場上每一位球手的表現,那麼定義一個分數:高於或者低於標準杆的杆數值。因此,如果最初兩個洞標準杆為4和5,而實際球手用了4杆和6杆,則分數為“1”(即高於標準杆1杆)。
球場類
球場名稱和標準杆數分別用String和一個int數組來實現。除了setter-和getter-方法外,還需要一個方法來得到每一個洞所對應的標準杆數。我們就將它聲明為“parUpTohole(int n)”。以下是我給出的類代碼:
package hansen.playground;
import java.util.*;
public class Cource ...{
private String name; // name of cource
private int[] par; // the par for each hole
/**//*
* Set the name of the course
*/
public void setName(String name) ...{
this.name = name;
}
/**//*
* Set the par for the cource
*/
public void setPar(int[] par) ...{
this.par = par;
}
/**//*
* Get the number of holes for the course
*/
public int getNumberOfHoles() ...{
return par.length;
}
/**//*
* Return the par for a given hole
*/
public int parForHole(int hole) ...{
return par[hole-1];
}
/**//*
* Return the par from hole 1 and up to a given hole
*/
public int parUpToHole(int hole) ...{
int sum = 0;
for ( int i = 0; i < hole; i++ ) ...{
sum += par[i];
}
return sum;
}
出於簡單,沒有在樣本中引入方法調用錯誤檢查(即在調用“getNumberOfHoles”方法前必須先調用“setPar”)。
對Course類的測試
通過調用Course類的方法,可以編寫程式測試“parUpToHoles”方法是否能夠得到預定的結果。我們假定球場為英格蘭美麗、著名的“St. Andrews”:
Course c = new Course();
c.setName("St. Andrews");
int[] par = ...{4,4,4,4,5,4,4,3,4,4,3,4,4,5,4,4,4,4};
c.setPar(par);
第1洞與第2洞標準杆之和顯然為4+4=8,所以可以編寫下面這樣的代碼進行測試:
if ( c.parUpToHole(2) != 8 ) ...{
System.out.println("*** Error in Course.parUpToHole: par for 2 holes not 8");
}
如果運行上面的代碼獲得一個錯誤資訊的話,那我們就有一個bug需要修複了。如果她只是默默地運行,哈哈,那就一切正常。
你可以寫一段代碼用來測試這18個洞,但大多數程式員知道只需要測試邊界值,即0個和18個洞,以及中間幾個值就可以達到要求。例如:
if ( c.parUpToHole(0) != 0 ) ...{
System.out.println("*** Error in Course.parUpToHole: par for 0 holes not 0");
}
if ( c.parUpToHole(2) != 8 ) ...{
System.out.println("*** Error in Course.parUpToHole: par for 2 holes not 8");
}
if ( c.parUpToHole(8) != 72 ) ...{
System.out.println("*** Error in Course.parUpToHole: par for 8 holes not 72");
}
上面的代碼,比較了一些值,然後根據比較的結果進行相應的處理,儘管實際有效,卻缺乏代碼的藝術性。通過這個程式,可以對"parUpToHole"進行單元測試,運行後,我們將讚賞地肯定這個方法是如預定的那樣工作。
其實,我們可以做得更加漂亮……