junit4備忘錄

簡介

JUnit是一個Java語言的單元測試框架。它由Kent Beck和Erich Gamma創建,逐漸成爲源於Kent Beck的sUnit的xUnit家族中最爲成功的一個。html

測試用例不是用來證實你(的邏輯)是對的,而是用來證實你(的斷言)沒有錯。java

junit3與junit4區別

  1. 在JUnit3中須要繼承TestCase類,JUnit4不須要繼承任何類;git

  2. 在JUnit3中須要覆蓋TestCase中的setUp和tearDown方法,其中setUp方法會在測試執行前被調用以完成初始化工做,而tearDown方法則在結束測試結果時被調用,用於釋放測試使用中的資源,而在JUnit4中,只須要在方法前加上@Before,@After ;github

  3. 在JUnit3中對某個方法進行測試時,測試方法的命令是固定的,例如對addBook這個方法進行測試,須要編寫名字爲tetAddBook的測試方法,而在JUnit4中沒有方法命令的約束,在方法的前面加上@Test,這就表明這個方法是測試用例中的測試方法;數據庫

  4. 新的斷言assertThat;數組

  5. @BeforeClass 和 @AfterClass 。在JUnit3,若是全部的test case僅調用一次setUp()和tearDown()須要使用TestSetup類;bash

  6. 測試異常處理@Test(expected = DataFormatException.class);框架

  7. 設置超時@Test(timeout = 1000);maven

  8. 忽略測試@Ignore;單元測試

  9. 集成測試(suiteTest)。

最大的不一樣是junit4基本用註解實現,更加靈活。

junit4與maven

添加進入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。

junit4的hello world

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做爲方法名的前綴(可選);

junit4運行流程

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在每一個測試方法先後各執行一次。

@Test中的參數

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起做用了。

批量運行測試類-測試套件(Suite)

咱們想運行全部的測試類的測試方法,難道咱們只能一個一個運行每個測試類麼,這多累啊。幸虧,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進行修飾。

他山之石

相關文章
相關標籤/搜索