JUnit是一個Java語言的單元測試框架。它由Kent Beck和Erich Gamma創建,逐漸成爲源於Kent Beck的sUnit的xUnit家族中最爲成功的一個。html
測試用例不是用來證實你(的邏輯)是對的,而是用來證實你(的斷言)沒有錯。java
在JUnit3中須要繼承TestCase類,JUnit4不須要繼承任何類;git
在JUnit3中須要覆蓋TestCase中的setUp和tearDown方法,其中setUp方法會在測試執行前被調用以完成初始化工做,而tearDown方法則在結束測試結果時被調用,用於釋放測試使用中的資源,而在JUnit4中,只須要在方法前加上@Before,@After ;github
在JUnit3中對某個方法進行測試時,測試方法的命令是固定的,例如對addBook這個方法進行測試,須要編寫名字爲tetAddBook的測試方法,而在JUnit4中沒有方法命令的約束,在方法的前面加上@Test,這就表明這個方法是測試用例中的測試方法;數據庫
新的斷言assertThat;數組
@BeforeClass 和 @AfterClass 。在JUnit3,若是全部的test case僅調用一次setUp()和tearDown()須要使用TestSetup類;bash
測試異常處理@Test(expected = DataFormatException.class);框架
設置超時@Test(timeout = 1000);maven
忽略測試@Ignore;單元測試
集成測試(suiteTest)。
最大的不一樣是junit4基本用註解實現,更加靈活。
添加進入maven的pom.xml的依賴中。設置scope爲test;
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
@BeforeClass: public static void方法,當前測試類,全部的測試方法運行前被執行;
@Before: public void方法,當前測試類,他會在全部方法運行結束後被執行;
@Test: public void方法,將一個普通的方法修飾成爲一個測試方法。具備兩個參數(可選):
timeout: 該測試方法容許執行的最大時間長度。單位ms
expected: 捕獲拋出的異常。xx.class
@After: public void方法,與@Before組成一對,會在每一個測試方法被運行後執行一次;
@AfterClass: public static void方法,與@BeforeClass組成一對,在當前測試類作完全部測試後執行的一個方法;
@Ignore: 所修飾的測試方法會被測試運行器忽略;
@RunWith: 更改測試運行器,自定義運行器須要繼承於org.junit.runner.Runner。
import org.junit.*; public class HelloTest { @Test public void testAdd(){ Assert.assertEquals("test add", 3, 1 + 2); System.out.print("Test add Ok"); } }
測試方法上必須使用@Test進行修飾;
測試方法必須使用public void 進行修飾,不能待任何的參數;
測試單元中的每一個方法必須能夠獨立測試,測試方法間不能有任何的依賴;
測試類使用Test做爲類名的後綴(可選);
測試方法使用test做爲方法名的前綴(可選);
public class FlowTest { @BeforeClass public static void init(){ System.out.println("test class before"); } @AfterClass public static void destory(){ System.out.println("test class after"); } @Before public void beforeTest(){ System.out.println("before test"); } @After public void afterTest(){ System.out.println("after test"); } @Test public void testAdd(){ Assert.assertEquals("test add", 3, 1 + 2); System.out.println("test add ok"); } @Test public void testSub(){ Assert.assertEquals("test subtraction", 3, 4 - 1); System.out.println("test sub ok"); } }
運行結果
test class before before test test add ok after test before test test sub ok after test test class after
@BeforeClass修飾的方法會在全部測試方法調用前執行。該方法爲靜態方法,比較適合加載配置文件。
@AfterClass修飾的方法會在全部測試方法調用後執行。該方法爲靜態方法,一般用來對資源的清理。好比關閉數據庫鏈接。
@Before與@After在每一個測試方法先後各執行一次。
public class TimeOutTest { @Test(timeout = 2000) public void testTimeOut(){ while (true){ System.out.println("I'm running!"); try { Thread.sleep(1000 *1); } catch (InterruptedException ignore) { } } } @Test(expected = ArithmeticException.class) public void testException(){ Assert.assertEquals(3,6/0); } }
運行結果
I'm running! I'm running! I'm running! org.junit.runners.model.TestTimedOutException: test timed out after 2000 milliseconds at java.lang.Thread.sleep(Native Method) at TimeOutTest.testTimeOut(TimeOutTest.java:15) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ...
testTimeOut雖然是死循環,但加了@Test(timeout)參數後仍是在2秒運行結束。
testException方法沒有拋出ArithmeticException,@Test中的expected起做用了。
咱們想運行全部的測試類的測試方法,難道咱們只能一個一個運行每個測試類麼,這多累啊。幸虧,junit4給咱們提供了一種方式一次運行全部的測試類-測試套件
。使用例子以下:
import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({FlowTest.class,TimeOutTest.class}) public class SuiteTest { }
測試suite就是組織測試類一塊兒運行;
寫一個做爲測試suite的入口類。這個類不包含任何方法;
更改suite入口類的測試運行器爲Suite.class;
將要運行的測試類做爲數組傳入到@Suite.SuiteClasses({})中。
不少時候,咱們須要對一個測試,輸入多組測試用例來驗證代碼的正確性。在junit4中,咱們不須要編寫n個測試方法。示例以下:
import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; import java.util.Collection; @RunWith(Parameterized.class) public class ParamsTest { private int expected; private int input1; private int input2; public ParamsTest(int expected, int input1, int input2){ this.expected = expected; this.input1 = input1; this.input2 = input2; } @Parameterized.Parameters public static Collection<Object[]> params(){ return Arrays.asList(new Object[][]{ {3,2,1}, {4,1,4} }); } @Test public void testAdd(){ Assert.assertEquals("add function",this.expected,this.input1 + this.input2); } }
運行結果
java.lang.AssertionError: add function Expected :4 Actual :5 <Click to see difference> at org.junit.Assert.fail(Assert.java:88) at org.junit.Assert.failNotEquals(Assert.java:834) at org.junit.Assert.assertEquals(Assert.java:645) at ParamsTest.testAdd(ParamsTest.java:34) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ...
第一組測試經過,第2組沒有
更改默認的測試運行器爲@RunWith(Parameterized.class);
聲明變量來存放預期值(隨便起名字,class中本身使用,expected/input1/input2);
爲測試類聲明一個帶有參數的公共構造器,並在其中爲之聲明變量賦值;
聲明一個返回值爲Collection的公共靜態方法 並用@Parameterized.Parameters進行修飾。
junit官網getstart: https://github.com/junit-team/junit4/wiki/Getting-started
junit4入門視頻: http://www.imooc.com/learn/356
junit4手冊:http://wiki.jikexueyuan.com/project/junit/suite-test.html