這篇文章將向你介紹Junit,一個用來在項目中進行測試和調試的工具。在介紹完TDD(以測試驅動開發)理論後,將進一步講解怎樣在流行的Eclipse中創建你本身的JUnit測試。向你展現如何測試Hello World這樣簡單的程序。
許多書上都討論了自動測試,可是隻有不多的著做注意到這麼一個問題,那就是怎樣把這些測試組織起來。隨着測試的增長,放置和調用這些測試卻變得更加麻煩。這將成爲一個重要問題,以致於出現了TDD,極限編程(XP)使TDD得以普及。另外,你能夠這樣理解TDD:經過測試來開發。
TDD的主要規範 :
在編寫程序代碼以前,與之對應的自動測試必須被寫好。甚至程序代碼並不存在,那也要看見一個失敗的測試結果。
在測試經過後,副本代碼必須被丟棄。
有一個具體步驟(可能指的是《Extreme Programming》)能夠被任何一個程序員來參考,而不須要特殊的其餘方法。在咱們開始寫測試以前,這些步驟(章節)應該被首先閱讀——怎樣組織自動測試。
講解一下不一樣種類的測試:
單元測試:檢測模塊(也就是類)的正確性。若是對象須要訪問外部的數據資源,例如數據庫,就須要模擬一個mock objects,但在實際中真實數據與測試環境是不一樣的。
客戶測試:這是功能性、系統、和驗收測試。用來測試總體的系統特性。在XP中,這些測試由用戶編寫。
綜合測試:介於用戶測試和單元測試之間的橋樑。綜合測試幫助測試應用程序的交互性。通常狀況下,mock objects不被用於綜合測試,它會增長測試時間。一樣,綜合測試常常依賴特殊的測試環境,例如數據庫送來的測試數據。綜合測試也須要用到外部類庫。例如爲J2EE應用程序進行綜合測試的類庫Cactus。解釋這些測試超出了本文的範圍,須要更加詳細的信息請參考[url]http://jakarta.apache.org/cactus/[/url]。
開發人員測試:這是用來讓開發人員檢驗本身代碼或新函數的。對於每個開發人員,只要有可能,就須要有更多的測試來檢驗代碼。組織這些測試和組織程序代碼同樣重要。
在如下章節,只要提到「測試」,那就指的是開發人員測試。
咱們幾乎準備好開始創建測試了,先應該爲咱們的測試選擇名字。你也許會說,「這不是問題:把‘Test’這個字放在類名前面,就行了!」不會這麼快!讓我來講一下這個步驟存在的問題:
在TDD中,被測試的類或者方法還不存在。
一個測試可以覆蓋多個方法,甚至多個類,這是可能的。
以上只是一些廣泛問題;還存在更多的問題。
讓我來提一個建議,在測試命名時:測試類的名字應該讓人一眼就知道這是一個測試類,且能說明它要測試什麼,注意是否和其餘類重名。按照以上建議作,就很簡單了,也不用擔憂名字太長或難聽。
即將在Eclipse中用JUnit工具建立咱們第一個測試了。假設你已經下載了一個最新的Eclipse版本。若是尚未,你應該去官方站點[url]http://www.eclipse.org[/url]下載。還須要JUnit,也能夠從[url]http://www.junit.org/[/url]下載。
運行Eclipse。新建一個workplace項目,點擊文件->新建->項目,選擇Java項目,點擊下一步。起一個項目名稱,例如ProjectWithJUnit。點擊完成。這樣就完成新項目的創建了。再來配置一下Eclipse,在構建路徑中添加JUnit類庫。在工具條上點擊項目->屬性,選擇Java構建路徑,庫,選擇添加外部JAR,瀏覽Junit被存儲的目錄,選擇junit.jar,點擊打開。你將會看見JUnit出如今庫的列表中。點擊肯定,讓Eclipse重建路徑。
如今開發咱們的「Hello World」例子。按照TDD的規則,應該在代碼創建之前先把測試寫好。爲了可以在某出開始,咱們假設將來的類名是HelloWorld,而且有一個方法Say(),這個方法返回String的值(例如「Hello World!」)。
創建測試,在ProjectWithJUnit的標題上面點擊右鍵,選擇新建->其餘,展開「Java」選項,選擇JUnit。在右邊的欄目對話框中選擇測試案例,而後下一步。參考圖1。
圖1. 在Eclipse中創建JUnit測試
在測試類這一欄中,寫上將要被測試的類名HelloWorld。選擇一個測試案例的名字,例如TestThatWeGetHelloWorldPrompt(是的,看上去很長,可是很清楚它的行爲。)點擊完成。
TestThatWeGetHelloWorldPrompt的代碼以下:
import junit.framework.TestCase;
public class TestThatWeGetHelloWorldPrompt
extends TestCase {
public TestThatWeGetHelloWorldPrompt(
String name) {
super(name);
}
public void testSay() {
HelloWorld hi = new HelloWorld();
assertEquals("Hello World!", hi.say());
}
public static void main(String[] args) {
junit.textui.TestRunner.run(
TestThatWeGetHelloWorldPrompt.class);
}
}
代碼並不複雜;只是有點不同凡響。然而,讓咱們考察一下細節。咱們繼承了JUnit的TestCase類,它在JUnit的javadocs定義爲「運行衆多測試的夾具。」JUnit也有TestSuite類,它是一組測試案例的集合,但在本文中不作討論。
創建測試案例的步驟以下:
一、創建一個junit.framework.TestCase的實例。
二、定義一些以「test」開頭的無返回方法(例如testWasTransactionSuccessful(),testShow(),等等)。
TestThatWeGetHelloWorldPrompt.java包含這些:TestCase的子類和一個叫作testSay()的方法。這個方法調用了assertEquals()函數,它用來比較咱們預期的值和由say()返回的值。
main()方法用來運行測試和顯示輸出的。JUnit的TestRunner處理測試,提供基於圖像和文本的輸出表現形式。咱們使用基於文本的版本,由於Eclipse支持它,且也適合咱們。當開始運行後,基於文本的版本測試會以文本形式輸出,Eclipse會把這些輸出自動變成圖像界面的輸出。
按照TDD規範,首次運行測試,應該故意讓它失敗。點擊運行->運行爲->Junit測試(記住TestThatWeGetHelloWorldPrompt.java應該被突出的顯示在包資源管理器中)。在左邊窗口,應該看見JUnit窗口而不是包資源管理器,它顯示一個紅條,一次失敗的測試,具體的失敗緣由參看圖2。若是沒有自動顯示這些內容,點擊JUnit標籤(在底部的左邊)。
圖2. JUnit中失敗的測試
很好!但卻失敗了。如今咱們來創建被測試代碼:在包資源管理器窗口的ProjectWithJUnit標題上右擊,選擇新建->類。選擇類名,咱們已經假設了它叫HelloWorld,而後直接點擊完成。爲HelloWorld.java填入下列代碼:
public class HelloWorld {
public String say() {
return("Hello World!");
}
}
這段代碼很簡單,甚至不須要註解,咱們再來看看結果。按照上面描述過的方式,在JUnit的窗口中顯示了一個綠條,參看圖3。綠條證實測試成功。
圖3. JUnit中成功的測試
如今,咱們想再讓測試失敗一次,但緣由不一樣。這有助於展現JUnit測試中不一樣的報錯信息。修改assertEquals()代碼,把「Hello World!」變成「Hello Me!」。當再次運行JUnit時,結果變成了紅條,在JUnit窗口的底部輸出了失敗緣由,參看圖4。
圖4. JUnit中的ComparisonError
最後,我想說一下關於測試是開發過程當中的必要部分的話題。測試代碼一直是開發中的重要部分。通過近幾年的發展,已獲得了很大的提升,這要歸功於強大的理論研究(好比「expectations-based development」等等),和快速發展的測試工具包,還有測試過程的改進。若是你對這篇文章感興趣,那請你花一些時間來正式的學習一下測試理論吧,這對你的工做頗有用。