近期寫單元測試計劃,公司準備把junit3.8升級到j(luò)unit4以上的版本,所以研究了一下,寫下學習過程和心得體會,為了鞏固學習成果,所以把學習心得寫下來加深印象,也供需要的朋友查閱,少走彎路。
好了,廢話不多說,直接開始: 假設(shè)我們要寫一個整數(shù)除法和乘法的類,并且給他寫測試用例: 1) 建立Math類 工具是eclipse3.3
/** * @author bulargy.j.bai * @mail bulargy@gmail.com * @創(chuàng)建時間:Mar 10, 2008 * @描述:一個整數(shù)除法和乘法的工具類 */ public class Math { public static int divide(int x,int y) { return x/y; } public static int multiple(int x,int y) { return x*y; } } 2) 建立測試用例 選中需要建立測試用例的包,選擇new->other->JUnit Test Case。 有5個方法可以選擇: setUp()方法在測試方法前調(diào)用,一般用來做測試準備工作。 tearDown()方法在測試方法后調(diào)用,一般作測試的清理工作。 setUpBeforeClass()方法在整個類初始化之后調(diào)用,一般用來做測試準備工作。 tearDownAfterClass()方法在整個類結(jié)束之前調(diào)用,一般作測試的清理工作。 constructor()為是否包含構(gòu)造方法。 自動生成的代碼如下:
/** * @author bulargy.j.bai * @mail bulargy@gmail.com * @創(chuàng)建時間:Mar 11, 2008 * @描述: */ public class MathTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } @Test public void testDivide() { fail("Not yet implemented"); } @Test public void testMultiple() { fail("Not yet implemented"); } } 說明: @BeforeClass標簽注釋的方法用于在整個類測試過程的初始化后調(diào)用一次,@AfterClass標簽注釋的方法則是整個測試類結(jié)束之前調(diào)用一次。這2個標簽的搭配可以避免使用@Before、@After標簽組合在每個測試方法前后都調(diào)用的弊端,減少系統(tǒng)開銷,提高系統(tǒng)測試速度。(不過對環(huán)境獨立性要求較高的測試還是應(yīng)當使用@Before、@After來完成) @Test標簽用來標注待測試的方法,按照類中聲明的順序執(zhí)行。 我們在testDivide方法加入測試代碼,分別測試三種情況: a. 完全正確也沒有可能出錯的數(shù)據(jù),如:9除3 結(jié)果必須等于3 b. 可能有問題的邊緣數(shù)據(jù),如:10除3 結(jié)果也必須等于3 c. 錯誤的數(shù)據(jù),如:10除0 必須拋出異常 忽略testMultiple方法 代碼如下:
@Test(expected=ArithmeticException.class) public void testDivide() { assertEquals(3,Math.divide(9,3)); assertEquals(3,Math.divide(10,3)); Math.divide(10,0); //除數(shù)不能為0,會拋出異常 } @Ignore("忽略乘法測試") @Test public void testMultiple() { } 說明: Junit4為測試方法增加了判斷異常的方式,避免了以前還要通過try/catch塊捕捉異常再拋出的復(fù)雜方式,簡單的這樣聲明“@Test(expected=ArithmeticException.class)”Junit4就會檢查此方法是否拋出ArithmeticException異常,如果拋出則測試通過,沒拋出則測試不通過(@Test標簽還有一些其他參數(shù),例如超時測試@Test(timeout=1)這樣,但是由于并不能準確反應(yīng)實際時間,所以應(yīng)用較少,經(jīng)過我測試誤差太大絕對不適合拿來做超時測試的) @Ignore標簽會告訴Junit4忽略它所標注的方法,例如數(shù)據(jù)庫不可用時可以用此標注標注一些測試數(shù)據(jù)庫連接的方法來避免測試失敗。 3) 運行測試 系統(tǒng)會打開JUnit透視圖,如果測試全部通過,則顯示顏色條為綠色;我們將assertEquals(3,Math.divide(9,3));改成assertEquals(2,Math.divide(9,3));則顯示顏色條為紅色,我們可以對錯誤或者故障的地方進行追蹤。 4) 創(chuàng)建測試套件 測試套件可以將多個測試用例合在一起測試,將相關(guān)的測試用例合成一個測試套件,在做一個修改后,只需要運行測試套件就可以,不需要運行每一個測試用例。 Junit4沒有采用以前的套件測試方法,同樣使用annotation的方式來進行。簡單在你所要構(gòu)建測試套件的包里創(chuàng)建一個文件,一般以包名+4Suite 下面我在上面的測試包中復(fù)制一下之前的測試類并且一個改名字叫做MathTestAnother,新建一個class類叫做Uitl4Suite,代碼如下:
import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; /** * @author bulargy.j.bai * @mail bulargy@gmail.com * @創(chuàng)建時間:Mar 11, 2008 * @描述:util包的測試套件 */ @RunWith(Suite.class) @SuiteClasses({MathTest.class, MathTestAnother.class}) public class Util4Suite { } 說明: 通過@RunWith和@SuiteClasses標簽來注釋一個空的包含無參數(shù)構(gòu)造函數(shù)的類來作為套件類,將需要組成套件運行的類加到@SuiteClasses的屬性中即可。 可以看到運行套件類的結(jié)果是2個測試類都進行了測試。 5) 參數(shù)測試 修改 testMultiple
//@Ignore("忽略乘法測試") @Test public void testMultiple() { assertEquals(result,Math.multiple(faciend,multiplicator)); } 編寫參數(shù)方法:
@Parameters public static Collection multipleValues() { return Arrays.asList(new Object[][] { {3, 2, 6 }, {4, 3, 12 }, {21, 5, 105 }, {11, 22, 242 }, {8, 9, 72 }}); } 說明: 需要使用@Parameters標簽注解一個靜態(tài)的返回集合對象的方法 增加成員變量和構(gòu)造函數(shù):
int faciend; int multiplicator; int result; public MathTest(int faciend, int multiplicator, int result) { this.faciend = faciend; this.multiplicator = multiplicator; this.result = result; } 最后在給測試類增加如下注釋:
@RunWith(Parameterized.class) 完整的循環(huán)測試代碼如下:
import static org.junit.Assert.*; import java.util.Arrays; import java.util.Collection; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; /** * @author bulargy.j.bai * @mail bulargy@gmail.com * @創(chuàng)建時間:Mar 11, 2008 * @描述: */ @RunWith(Parameterized.class) public class MathTest { int faciend; int multiplicator; int result; public MathTest(int faciend, int multiplicator, int result) { this.faciend = faciend; this.multiplicator = multiplicator; this.result = result; } @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } @Test(expected=ArithmeticException.class) public void testDivide() { assertEquals(3,Math.divide(9,3)); assertEquals(3,Math.divide(10,3)); Math.divide(10,0);//除數(shù)不能為0,會拋出異常 } //@Ignore("忽略乘法測試") @Test public void testMultiple() { assertEquals(result,Math.multiple(faciend,multiplicator)); } @Parameters public static Collection multipleValues() { return Arrays.asList(new Object[][] { {3, 2, 6 }, {4, 3, 12 }, {21, 5, 105 }, {11, 22, 242 }, {8, 9, 72 }}); } } OK,大功告成。測試看看吧,測試類跑了5次~~。 大概就這么多體會了,總得來說JUnit4以后測試還是很方便的,順便這個是僅僅是為了做例子,實際使用中由于JUnit4不再受命名的限制,所以應(yīng)該劃分更細粒度的測試來完成,一個方法的正確,異常,錯誤及邊界數(shù)據(jù)完全可以分開來寫測試方法。由于大部分情況資源只用加載和釋放一次就足夠,大大提高的測試的速度,再也不會有以前那樣點開測試然后去泡咖啡的情況出現(xiàn)了~~呵呵~~ |
|
來自: helloworld_sh > 《我的圖書館》