基於Eclipse的單元測試框架Junit進階
導言
在學習了上篇入門之后,如果你有所嘗試,相信已經把持不住想要更高級的功能了,下面我們進入正題。(先把上次的簡介部分放過來,因為這次會用到Before和After)
Junit簡介
JUnit是一個Java語言的單元測試框架,應用它進行單元測試,能夠准確、快速地保證程序基本模塊的正確性。Junit通過注解的方式來識別測試方法,目前支持的主要注解有:
- @BeforeClass:一次性setup,全局只執行一次,第一個運行
- @AfterClass:一次性teardown,全局也只執行一次,最后一個運行
- @Before:每次都在測試方法運行之前運行
- @After:每次都在測試方法運行之后運行
- @Test:測試方法
一個JUnit4的單元測試用例執行順序為:
@BeforeClass -> @Before -> @Test -> @After -> @AfterClass,其中黑體部分可被多次執行。
添加Before&After
這個比較簡單,只需要在新建測試程序的時候添加兩個小選項就好,如圖所示。

那么,這兩個方法是做什么的呢?setUp()顧名思義,就是在每次測試開始之前要做的一些初始化工作,比如,清空隊列、還原執行狀態等;而tearDown()呢?也很容易理解,就是在某個testcase結束之后所做的一些回收、清除或者恢復工作。總之都是為了保證測試的高效進行。
測試異常處理
有時候我們的方法會拋出異常,那么測試的時候如果遇到會發現testcase顯示為error,但是我們正是想讓程序在某種情況下拋出異常,該如何處理呢?很簡單,只需要添加一個expected就可以解決啦!
@Test(expected = ArithmeticException.class)
public void testDivideByZero(){
cal.divide(0);
}
這樣,測試起來關於異常的error就可以消失不見了。
參數化測試
在某方法的分支較多、或者該方法的參數分很多情況、或者參數有較多特殊值,但是又需要較高的測試覆蓋率時,我們就需要用到這種參數化的測試了,因為不然你的代碼量會急劇飆升,而且會產生很多重復代碼段,對於有程序潔癖的你是否能忍受呢?
我們還是舉之前的例子,比如要測試乘方,我們也許會分3類測試:正數的平方,0的平方,負數的平方。如何參數化呢?
package JunitTest;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class ParaTest {
private static Calculator Cal = new Calculator();
private double para; //parameter passed to method
private double expcted; //expected result
@Before
public void setUp() throws Exception {
Cal.clear();
}
@Parameters
public static Collection db(){
return Arrays.asList(new Object[][]{
/*{para, expected}*/
{-6, 36},
{0, 0},
{3, 9}
});
}
public ParaTest(double para, double expected) {
// TODO Auto-generated constructor stub
this.para = para;
this.expcted = expected;
}
@Test
public void testSquare() {
Cal.square(this.para);
assertEquals(this.expcted, Cal.getResult(), 0.0001);
}
}
當然,這只是一個特例,在實際應用的時候不一定僅僅只有兩個參數,也不一定一個參數是結果的期望值,總之靈活使用Collection中的東西就好,但切記,參數一定要按順序書寫,把握好db()和構造方法中的參數對應關系。
那么,這段代碼如何實現的呢?做如下分析:
- 每一個參數化測試都要有自己的專屬類,不能共用
- 為此類指定Runner為ParameterizedRunner,通過在類的聲明處添加
@RunWith(Parameterized.class)修飾來實現 - 在專屬類中確定定義要使用的變量,該例有兩個變量(para、expected)
- 用Collection框架讓測試數據組的處理標准化,用
@Parameters對其修飾 - 構造函數(constructor)的定義,保證與方法db()中參數的對應關系
限時測試
一般情況下,在測試時間過長、或者測試出現停滯狀況時,我們都能夠從JUnit的布局(layout)中看出來,從而定位到出現耗時較多(一般為死循環)的方法。所以該測試方式的作用主要體現在預防層面,而並非測試層面,這里就不贅述了。該方式可通過在注解@Test之后添加timeout來實現: @Test(timeout = 1000) ,注意此處的time單位為毫秒(ms)。
以上就是我學到的JUnit應用,之后會有覆蓋率統計相關的更新。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接(http://www.cnblogs.com/Echo-41/p/6921252.html)
