JBuilder2005單元測試之創建測試用例
我們先為Subsection類創建測試用例。
1.在編輯器中打開Subsection.java文件,使其處理激活態。
2.File->New...->Test->在Test頁的對象庫中雙擊Test Case圖標,啟動創建測試用例的向導,如下圖所示:
·Select class:測試的目標類,默認為當前編輯器中打開的類,也可以通過其后的…按鈕選擇工程中其他的類。
·Avaiable methods:列出了測試目標類的所有public、protected和默認可視域的方法,private方法不列出。只要你測試了前三者的方法,private也被間接測試到了。這里,我們選擇getValue()和sign()方法。
點擊Next到下一步。
3.設置測試用例類的類名。
JBuilder為測試用例類指定了一個默認的類名,即Test<業務類名>,包名和業務類包名一致。接受默認的值,直接按Finish創建TestSubsection測試用例類。
實戰經驗:
雖然在物理上,業務類和測試用例類被放在不同目錄下,但在工程窗格的資源樹中,業務類和測試用例還是擠在了一起。如果一個包下有多個業務類,加上它們相應的測試用例類,將顯得更加擁擠不堪。所以最好將測試用例放到不同的包中,如com.super.bdbj包中的所有業務類的測試用例放到test.super.bdbj目錄下,這樣將徹底解決測試用例和業務類的物理和邏輯上的分離,使工程窗格中的資源樹更加整潔明了。
TestSubsection類的代碼如下所示:
代碼清單 錯誤!文檔中沒有指定樣式的文字。向導生成的TestSubsection類
在第5行聲明了一個Subsection的成員變量,并在setUp()中實例化這個變量(第7行),在tearDown()中釋放這個變量(第12行),其實這三部分就構成了一個測試固件。當然,由于我們的getValue()、sign()方法都是靜態方法,所以并不需要這個固件,在測試方法中直接調用方法就可以了,如Subsection.getValue(),但為了加強概念上的認識,我們特別予以保留。
第16'22行的testGeValue()方法,和第24'30行的testSign(),就是在向導第1步所選擇的需要測試的API方法對應的測試方法。JBuilder當然不可能知道我們API的邏輯規則,所以它僅提供了一個框架式的測試代碼,需要我們發揮聰明才智通過assertXxx()定制覆蓋性強的測試規則。
注意:
你也可以手工在TestSubsection類中添加測試方法,測試方法必須遵照public void testXxx()樣式規范。所以如果你想在測試用例類中添加一個輔助性的方法,請不要以test為前綴,在更改業已生成的測試方法名稱時,也要保證不去除方法前的test前綴,測試運行器籍此查找測試用例類中的測試方法。
下面,分別刪除testGetValue()和testSign()方法體中的代碼,用以下粗體代碼替換之:
代碼清單 錯誤!文檔中沒有指定樣式的文字。添加測試規則后的TestSubsection類
打蛇打七寸,擒賊先擒王,抓Bug還須在那些關鍵點上下功夫,特殊轉換點是最容易出現問題的熱點地區,需要給予特別的關注。所以我們為getValue()設置了6個測試點,而為sign()方法設置了3個測試點。
在工程窗格資源樹中找到TestSubsection.java文件,右擊在彈出的菜單中選擇Run Test using "TestSubsection1",JBuilder利用JBTestRunner測試運行器運行這個測試用例,在信息窗格中出現如下的運行器界面:
JBTestRunner窗口左邊為3個標簽頁,它們的作用在下表的說明:
表 錯誤!文檔中沒有指定樣式的文字。JBTestRunner窗口標簽頁說明
當沒有發生失敗的測試時,測試進度條顯示為綠色,否則顯示為紅色。對于測試用例很少的情況你看不到它的效果,如果成百上千的測試用例一起運行,這個進度條的作用是顯而易見了。進度條右邊是測試結果統計信息:包括測試方法總數和成功數,統計信息右邊是測試所花費的時間。
右幀是測試失敗的引發點,單擊鏈接,JBuilder自動定位到測試用例測試失敗的地方,在本例里,JBuilder將定位到代碼清單 錯誤!文檔中沒有指定樣式的文字。添加測試規則后的TestSubsection類的代碼的第17行,即:assertEquals(y5, subsection.getValue(d5));所在的行。
說明測試失敗是由這個斷言引起的,由于這個斷言測試入參大于32時的函數返回值正確性,所以我們就知道程序沒有考慮到返回值超過int類型范圍的情況。返回到代碼清單 錯誤!文檔中沒有指定樣式的文字。前文分段函數代碼中將第13'15行被注釋的代碼放出來,重新運行測試,你將發現測試全部通過了。
這也說明,編寫一個有效測試用例并非易事,程序路徑100%覆蓋,完美的測試用例往往很難達到。當然,你可以依照一些經驗性的原則,其中最大的一條就是:關注關鍵點。測試用例編寫的技巧,超過了本文的范圍,讀者可以自行參考相關的書籍。
提示:
有時,JBTestRunner右邊的幀窗口雖然內容已經超出,但滾動條卻沒有顯示出來,想來應該是JBuilder一個小小的Bug吧。你可以在幀窗口中右擊,在彈出的菜單中去除Word Wrap設置項,或者手工移動一下左右兩幀間的分隔欄,滾動條就會顯示出來了。
1.在編輯器中打開Subsection.java文件,使其處理激活態。
2.File->New...->Test->在Test頁的對象庫中雙擊Test Case圖標,啟動創建測試用例的向導,如下圖所示:
![]() 圖 錯誤!文檔 中沒有指定樣式的文字。指定測試的方法 |
·Select class:測試的目標類,默認為當前編輯器中打開的類,也可以通過其后的…按鈕選擇工程中其他的類。
·Avaiable methods:列出了測試目標類的所有public、protected和默認可視域的方法,private方法不列出。只要你測試了前三者的方法,private也被間接測試到了。這里,我們選擇getValue()和sign()方法。
點擊Next到下一步。
3.設置測試用例類的類名。
![]() 圖 錯誤!文檔中沒有指定樣式的文字。指定測試用例類的名稱 |
JBuilder為測試用例類指定了一個默認的類名,即Test<業務類名>,包名和業務類包名一致。接受默認的值,直接按Finish創建TestSubsection測試用例類。
實戰經驗:
雖然在物理上,業務類和測試用例類被放在不同目錄下,但在工程窗格的資源樹中,業務類和測試用例還是擠在了一起。如果一個包下有多個業務類,加上它們相應的測試用例類,將顯得更加擁擠不堪。所以最好將測試用例放到不同的包中,如com.super.bdbj包中的所有業務類的測試用例放到test.super.bdbj目錄下,這樣將徹底解決測試用例和業務類的物理和邏輯上的分離,使工程窗格中的資源樹更加整潔明了。
TestSubsection類的代碼如下所示:
代碼清單 錯誤!文檔中沒有指定樣式的文字。向導生成的TestSubsection類
| 1. package chapter25; 2. 3. import junit.framework.*; 4. public class TestSubsection extends TestCase { 5. private Subsection subsection = null; 6. protected void setUp() throws Exception { 7. super.setUp(); 8. subsection = new Subsection(); 9. } 10. 11.protected void tearDown() throws Exception { 12.subsection = null; 13.super.tearDown(); 14.} 15. 16.public void testGetValue() { 17. int d = 0; 18. int expectedReturn = 0; 19. int actualReturn = subsection.getValue(d); 20. assertEquals("return value", expectedReturn, actualReturn); 21. /**@todo fill in the test code*/ 22.} 23. 24.public void testSign() { 25.double d = 0.0; 26.int expectedReturn = 0; 27.int actualReturn = subsection.sign(d); 28.assertEquals("return value", expectedReturn, actualReturn); 29./**@todo fill in the test code*/ 30.} 31. } |
在第5行聲明了一個Subsection的成員變量,并在setUp()中實例化這個變量(第7行),在tearDown()中釋放這個變量(第12行),其實這三部分就構成了一個測試固件。當然,由于我們的getValue()、sign()方法都是靜態方法,所以并不需要這個固件,在測試方法中直接調用方法就可以了,如Subsection.getValue(),但為了加強概念上的認識,我們特別予以保留。
第16'22行的testGeValue()方法,和第24'30行的testSign(),就是在向導第1步所選擇的需要測試的API方法對應的測試方法。JBuilder當然不可能知道我們API的邏輯規則,所以它僅提供了一個框架式的測試代碼,需要我們發揮聰明才智通過assertXxx()定制覆蓋性強的測試規則。
注意:
你也可以手工在TestSubsection類中添加測試方法,測試方法必須遵照public void testXxx()樣式規范。所以如果你想在測試用例類中添加一個輔助性的方法,請不要以test為前綴,在更改業已生成的測試方法名稱時,也要保證不去除方法前的test前綴,測試運行器籍此查找測試用例類中的測試方法。
下面,分別刪除testGetValue()和testSign()方法體中的代碼,用以下粗體代碼替換之:
代碼清單 錯誤!文檔中沒有指定樣式的文字。添加測試規則后的TestSubsection類
| 1. … 2. public class TestSubsection extends TestCase 3. { 4. … 5. public void testGetValue() { 6. int d1 = -3,y1 = 3; 7. int d2 = -2,y2 = 4; 8. int d3 = 0 ,y3 = 100; 9. int d4 = 2 ,y4 = 8; 10.int d5 = 33 ,y5 = 32768; 11.int d6 = 33 ,y6 = Integer.MAX_VALUE; 12.assertEquals(y1,subsection.getValue(d1)); 13.assertEquals(y2,subsection.getValue(d2)); 14.assertEquals(y3,subsection.getValue(d3)); 15.assertEquals(y4,subsection.getValue(d4)); 16.assertEquals(y5,subsection.getValue(d5)); 17.assertEquals(y6,subsection.getValue(d6)); 18.} 19. 20.public void testSign() { 21. double d1 = -1.0, d2 = 0.0, d3 = 1.0; 22. int y1 = 1, y2 = 0, y3 = 1; 23. assertEquals(y1, subsection.sign(d1)); 24. assertEquals(y1, subsection.sign(d1)); 25. assertEquals(y1, subsection.sign(d1)); 26. } 27. } |
打蛇打七寸,擒賊先擒王,抓Bug還須在那些關鍵點上下功夫,特殊轉換點是最容易出現問題的熱點地區,需要給予特別的關注。所以我們為getValue()設置了6個測試點,而為sign()方法設置了3個測試點。
在工程窗格資源樹中找到TestSubsection.java文件,右擊在彈出的菜單中選擇Run Test using "TestSubsection1",JBuilder利用JBTestRunner測試運行器運行這個測試用例,在信息窗格中出現如下的運行器界面:
![]() 圖 錯誤!文檔中沒有指定樣式的文字。JBTestRunner運行器界面 |
JBTestRunner窗口左邊為3個標簽頁,它們的作用在下表的說明:
表 錯誤!文檔中沒有指定樣式的文字。JBTestRunner窗口標簽頁說明
| 標簽頁圖標 | 說明 |
![]() | 如果測試沒有錯誤,該標簽頁為默認顯示的標簽頁。形成一棵測試套件->測試用例->測試方法3級的級聯樹。樹中每個節點均有一個狀態指示圖標。 表示通過測試,而 表示未通過測試。點擊未通過測試的節點,右邊幀列出了錯誤跟蹤跡,通過這個跟蹤跡可以找到哪個測試規則(斷言方法assertXxx())未通過。 |
![]() | 測試錯誤頁,如果發生了測試錯誤,該頁被默認顯示。列出所有發生錯誤的測試,該頁是 標簽頁的子集。 |
![]() | 該標簽頁中顯示出所有輸出到控制臺的信息,如測試用例中有通過System.out.println()輸出信息,則這些信息在此查看。 |
當沒有發生失敗的測試時,測試進度條顯示為綠色,否則顯示為紅色。對于測試用例很少的情況你看不到它的效果,如果成百上千的測試用例一起運行,這個進度條的作用是顯而易見了。進度條右邊是測試結果統計信息:包括測試方法總數和成功數,統計信息右邊是測試所花費的時間。
右幀是測試失敗的引發點,單擊鏈接,JBuilder自動定位到測試用例測試失敗的地方,在本例里,JBuilder將定位到代碼清單 錯誤!文檔中沒有指定樣式的文字。添加測試規則后的TestSubsection類的代碼的第17行,即:assertEquals(y5, subsection.getValue(d5));所在的行。
說明測試失敗是由這個斷言引起的,由于這個斷言測試入參大于32時的函數返回值正確性,所以我們就知道程序沒有考慮到返回值超過int類型范圍的情況。返回到代碼清單 錯誤!文檔中沒有指定樣式的文字。前文分段函數代碼中將第13'15行被注釋的代碼放出來,重新運行測試,你將發現測試全部通過了。
這也說明,編寫一個有效測試用例并非易事,程序路徑100%覆蓋,完美的測試用例往往很難達到。當然,你可以依照一些經驗性的原則,其中最大的一條就是:關注關鍵點。測試用例編寫的技巧,超過了本文的范圍,讀者可以自行參考相關的書籍。
提示:
有時,JBTestRunner右邊的幀窗口雖然內容已經超出,但滾動條卻沒有顯示出來,想來應該是JBuilder一個小小的Bug吧。你可以在幀窗口中右擊,在彈出的菜單中去除Word Wrap設置項,或者手工移動一下左右兩幀間的分隔欄,滾動條就會顯示出來了。




表示通過測試,而
表示未通過測試。點擊未通過測試的節點,右邊幀列出了錯誤跟蹤跡,通過這個跟蹤跡可以找到哪個測試規則(斷言方法assertXxx())未通過。
