Java單元測試-快速上手Junit(進階)


基於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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM