單元測試工具 TestNG 使用

本文首發於 jaychen.cc
做者 jaychenjava

寫一篇小文,介紹一下 Java 下單元測試工具 TestNG 的使用,代碼在 IDEA 環境在編寫。bash

單元測試,顧名思義,對系統中原子性的功能進行測試,通常狀況下是單元測試是針對某個功能函數的測試。編寫單元測試是系統開發中重要的一環,也是一項科學優雅的裝 X 方式。並且,編寫單元測試代碼並非一件很麻煩的事情,只要稍微學習就能夠掌握這項技能。網絡

TestNG 使用

快速體驗

在開始以前,須要引入 TestNG 庫,使用 maven 直接引入,在 pom.xml 添加依賴maven

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.8</version>
    <scope>test</scope>
</dependency>複製代碼

使用 IDEA 新建一個項目,目錄結構以下:函數

├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   └── resources
│   └── test複製代碼

新建一個 Demo.java 類,包含以下簡單代碼工具

public class Demo {
    public int add(int a, int b) {
        return a + b;
    }

    public int sub(int a, int b) {
        return a - b;
    }
}複製代碼

在 IDEA 下使用快捷鍵 Ctrl + Shift + t 爲其生成測試類單元測試

這裏能夠看到,咱們選擇了 TestNG 做爲單元測試庫,IDEA 自動爲咱們生成了單元測試類的類名,其命名規則爲:被測試類+Test。最後勾選要進行測試的方法,這裏我只選擇 add 方法。學習

肯定以後,會在 src/test/java 目錄下生成對應的類文件,能夠看到已經生成了 DemoTest.java 文件,其內容以下測試

public class DemoTest {
    @Test
    public void testAdd() throws Exception {

    }
}複製代碼

此時,咱們就能夠開始編寫測試代碼。這裏,單元測試的目的是爲了測試 Demo#add 這個函數的功能是否準確正常,因此咱們在 testAdd 中編寫代碼ui

@Test
public void testAdd() throws Exception {
    Demo d = new Demo();
    assertEquals(7, d.add(3, 4));
}複製代碼

這裏,使用了 assertEquals 進行斷言,這句話至關於說:d.add(3,4) 的結果應該是 7,你幫我執行下 add 看看是否是返回 7。好了,一個單元測試的用例完成,以後就能夠直接運行該測試方法,能夠看到輸出以下:

[TestNG] Running:
===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================複製代碼

代表這個測試經過,函數功能沒錯。若是咱們把代碼改爲 assertEquals(d.add(3, 4), 8);,那麼就會出現以下提示

Expected :8
Actual   :7
 <Click to see difference>


    at org.testng.Assert.fail(Assert.java:94)
    at org.testng.Assert.failNotEquals(Assert.java:494)
    ...........
===============================================
Default Suite
Total tests run: 1, Failures: 1, Skips: 0
===============================================複製代碼

代表 add 方法的返回結果和指望的不一樣,方法可能存在 bug。

這裏要注意一個問題,上面咱們對 add 進行一次測試經過,不表明 add 方法就不存在 bug。assertEquals(d.add(3, 4), 7); 只是一個測試用例。這裏要理清一個概念:add 函數編寫了一個單元測試函數 testAdd,以後咱們須要使用多個測試用例來測試 add 函數是否存在 bug。爲了證實 add 沒有 bug,須要考慮全部可能的狀況,包括 輸入爲0,輸入的 a,b 參數爲負數 等等儘可能的覆蓋全部可能性。因此一個嚴謹的測試應該以下:

@Test
public void testAdd() throws Exception {
    Demo d = new Demo();
    assertEquals(d.add(3, 4), 7);
    assertEquals(d.add(-3, 4), 1);
    assertEquals(d.add(-3, -4), -7);
    assertEquals(d.add(0, 4), 4);
    assertEquals(d.add(0, 0), 0);
}複製代碼

高級用法

上面的例子只是簡單用法,旨在讓初學者能夠快速上手瞭解 TestNG 的 用法,下面介紹一些高級用法來幫助咱們更好的進行單元測試。

@BeforeClass/@AfterClass@BeforeMethod/@AfterMethod

除了 @Test 註解,TestNG 還有兩對經常使用的註解:@BeforeClass/@AfterClass@BeforeMethod/@AfterMethod。這些註解的關係以下圖:

從上圖能夠看出,@BeforeMethod/@AfterMethod 是在 @Test 註解函數執行以前/以後執行的鉤子函數。在執行每個 @Test 註解函數執行以前/以後都會執行 @BeforeMethod/@AfterMethod 註解函數。

@BeforeClass/@AfterClass 的做用和 @BeforeMethod/@AfterMethod 相似,不一樣的是,@BeforeClass/@AfterClass 是在初始化類的時候執行,這就意味着 @BeforeClass/@AfterClass 只會執行一次,而 @BeforeMethod/@AfterMethod 執行次數和 @Test 註解函數個數同樣。

public class DemoTest {

    @BeforeClass
    public static void beforeClass() {
        System.out.println("before test....");
    }

    @BeforeMethod
    public void beforeTest() {
        System.out.println("before test...");
    }

    @Test
    public void testAdd() {

        int res = new Dao().add(1, 2);
        Assert.assertEquals(res, 3);
    }

    @Test
    public void testSub() {
        int res = new Dao().sub(1, 2);
        Assert.assertEquals(res, -1);
    }

    @AfterMethod
    public void afterTest() {
        System.out.println("after test....");
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("after class....");
    }
}複製代碼

執行上面的代碼,能夠看到 beforeClass/afterClass 只執行一次,而 beforeMethod/afterMethod 執行了兩次。

這裏還須要提一點:@BeforeClass/@AfterClass 註解的函數必須使用 static 修飾。

除了使用 assertEquals 斷言函數測試結果以外,TestNG 還提供了一些額外的測試狀況。

超時測試

@Test 註解中添加 timeOut 參數就能夠進行超時測試,@Test(timeOut=10) 表示測試方法的運行時間應該低於 10ms,若是超時者測試失敗。超時測試對於網絡鏈接類的測試至關有用。超時測試具體用法以下

@Test(timeOut = 1)
public void testSub() {
    int i =0;
    while (i < 1000000000) {
        i++;
    }
}複製代碼

異常測試

異常測試用於測試方法是否有拋出異常,經過 @Test(expected=NullPointerException.class) 來指定方法必須拋出 NullPointerException,若是沒有拋出異常或者拋出其餘異常則測試失敗。

@Test(expectedExceptions = NullPointerException.class)
public void testSub() {
    throw new  NullPointerException();
}複製代碼

依賴測試

有時候須要測試方法按照一個特定的順序被調用,這個時候須要使用 @Test 註解的 dependsOnMethods 參數來指定依賴方法和方法的執行順序

// test1 執行以前會先執行 test2, test3
@Test(dependsOnMethods = {"test2","test3"})
public void test1(){

}
@Test
public void test2(){

}
@Test
public void test3(){

}複製代碼

好了,TestNg 的使用就到這裏了,其實單元測試並非一件麻煩的事情,花上一些時間學習一下很快就很上手。過了 TestNg 下次說下 Mockito 的使用。

相關文章
相關標籤/搜索