TestNG-常用註解介紹

這篇文章將講解TestNG裏面常用的一些註解。

TestNG的註解大部分用在方法級別上。常用的註解列舉如下:

1. Before類別和After類別註解

  • @BeforeSuite
  • @AfterSuite
  • @BeforeTest
  • @AfterTest
  • @BeforeClass
  • @AfterClass
  • @BeforeMethod
  • @AfterMethod

上述的註解分爲Before類別和After類,我們可以在Before類別的註解方法裏面做一些初始化動作,如實例化數據庫連接、新建數據庫連接池、創建線程池、打開文件流等等。然後,我們可以在After類別的註解方法裏面做一些銷燬動作,如釋放數據庫連接、銷燬數據庫連接池、銷燬線程池或者關閉文件流等等。同一類別的不同註解會在不同的位置被調用,下面我們逐個介紹:

1.1 @BeforeSuite

被@BeforeSuite註解的方法,將會在testng定義的xml根元素裏面的所有執行之前運行。

1.2 @AfterSuite

被@AfterSuite註解的方法,將會在testng定義的xml根元素裏面的所有執行之後運行。

1.3 @BeforeTest

被@BeforeTest註解的方法,將會在一個元素定義的所有裏面所有測試方法執行之前運行。

1.4 @AfterTest

被@AfterTest註解的方法,將會在一個元素定義的所有裏面所有的測試方法執行之後運行。

1.5 @BeforeClass

被@BeforeClass註解的方法,將會在當前測試類的第一個測試方法執行之前運行。

1.6 @AfterClass

被@AfterClass註解的方法,將會在當前測試類的最後一個測試方法執行之後運行。

1.7 @BeforeMethod

被@BeforeMethod註解的方法,將會在當前測試類的每一個測試方法執行之前運行。

1.8 @AfterMethod

被@AfterMethod註解的方法,將會在當前測試類的每一個測試方法執行之後運行。

上面的說明,很抽象,也很亂,我們以一個例子來說明上面這些註解的用法:

新建TestNGAnnotationTestTestNGAnnotationTest2(TestNGAnnotationTest2TestNGAnnotationTest內容一致)

public class TestNGAnnotationTest {

    @BeforeSuite
    public void beforeSuite() {
        System.out.println(this.getClass().getName() + " beforeSuite");
    }

    @AfterSuite
    public void afterSuite() {
        System.out.println(this.getClass().getName() + " afterSuite");
    }

    @BeforeTest
    public void beforeTest() {
        System.out.println(this.getClass().getName() + " beforeTest");
    }

    @AfterTest
    public void afterTest() {
        System.out.println(this.getClass().getName() + " afterTest");
    }

    @BeforeClass
    public void beforeClass() {
        System.out.println(this.getClass().getName() + " beforeClass");
    }

    @AfterClass
    public void afterClass() {
        System.out.println(this.getClass().getName() + " afterClass");
    }

    @BeforeMethod
    public void beofreMethod() {
        System.out.println(this.getClass().getName() + " beforeMethod");
    }

    @AfterMethod
    public void afterMethod() {
        System.out.println(this.getClass().getName() + " afterMethod");
    }

    @Test
    public void test1() {
        System.out.println(this.getClass().getName() + " test1");
    }

    @Test
    public void test2() {
        System.out.println(this.getClass().getName() + " test2");
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

testng.xml裏面加入:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
  <test name="test1" >
    <classes>
       <class name="com.crazypig.testngdemo.TestNGAnnotationTest" />
       <class name="com.crazypig.testngdemo.TestNGAnnotationTest2" />
    </classes>
  </test>
</suite>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

運行testng測試,得到以下結果:

com.crazypig.testngdemo.TestNGAnnotationTest beforeSuite
com.crazypig.testngdemo.TestNGAnnotationTest2 beforeSuite
com.crazypig.testngdemo.TestNGAnnotationTest beforeTest
com.crazypig.testngdemo.TestNGAnnotationTest2 beforeTest
com.crazypig.testngdemo.TestNGAnnotationTest beforeClass
com.crazypig.testngdemo.TestNGAnnotationTest beforeMethod
com.crazypig.testngdemo.TestNGAnnotationTest test1
com.crazypig.testngdemo.TestNGAnnotationTest afterMethod
com.crazypig.testngdemo.TestNGAnnotationTest beforeMethod
com.crazypig.testngdemo.TestNGAnnotationTest test2
com.crazypig.testngdemo.TestNGAnnotationTest afterMethod
com.crazypig.testngdemo.TestNGAnnotationTest afterClass
com.crazypig.testngdemo.TestNGAnnotationTest2 beforeClass
com.crazypig.testngdemo.TestNGAnnotationTest2 beforeMethod
com.crazypig.testngdemo.TestNGAnnotationTest2 test1
com.crazypig.testngdemo.TestNGAnnotationTest2 afterMethod
com.crazypig.testngdemo.TestNGAnnotationTest2 beforeMethod
com.crazypig.testngdemo.TestNGAnnotationTest2 test2
com.crazypig.testngdemo.TestNGAnnotationTest2 afterMethod
com.crazypig.testngdemo.TestNGAnnotationTest2 afterClass
com.crazypig.testngdemo.TestNGAnnotationTest afterTest
com.crazypig.testngdemo.TestNGAnnotationTest2 afterTest
com.crazypig.testngdemo.TestNGAnnotationTest afterSuite
com.crazypig.testngdemo.TestNGAnnotationTest2 afterSuite
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

這裏給出一張圖,方便更好地理解這些註解方法的執行位置: 
show-testng-annotation-run-position

我們可以根據自身需求,選擇特定的位置去執行一些初始化動作,以及一些銷燬動作。假如你需要針對整個測試suite做初始化動作,那麼應該選擇在被@BeforeSuite註解的方法裏面執行。如果需要針對一個<test>裏面的所有測試類做初始化動作,那麼可以選擇在被@BeforeTest註解的方法裏面執行。如果需要針對一個特定的測試類做初始化動作,那麼應該選擇在被@BeforeClass註解的方法裏面執行。最後,假如你想在每一個測試方法執行前做初始化動作,那麼應該選擇@BeforeMethod。銷燬的選擇與初始化類似,這裏不再贅述。

2. @Test 註解

@Test 註解是TestNG的核心註解,被打上該註解的方法,表示爲一個測試方法,類比JUnit是一個道理(JUnit也是用了這個註解,在使用TestNG時候注意導包別導錯)。

這個註解有多個配置屬性,用法爲:

@Test(param1 = ..., param2 = ...)
  • 1
  • 1

常見取值說明如下:

  • alwaysRun : 如果=true,表示即使該測試方法所依賴的前置測試有失敗的情況,也要執行
  • dataProvider : 選定傳入參數的構造器。(@DataProvider註解將在後面章節介紹)
  • dataProviderClass : 確定參數構造器的Class類。(參數構造器首先會在當前測試類裏面查找,如果參數構造器不在當前測試類定義,那麼必須使用該屬性來執行它所在的Class類)
  • dependsOnGroups : 確定依賴的前置測試組別。
  • dependsOnMethods : 確定依賴的前置測試方法。
  • description : 測試方法描述信息。(建議爲每個測試方法添加有意義的描述信息,這將會在最後的報告中展示出來)
  • enabled : 默認爲true,如果指定爲false,表示不執行該測試方法。
  • expectedExceptions : 指定期待測試方法拋出的異常,多個異常以逗號(,)隔開。
  • groups : 指定該測試方法所屬的組,可以指定多個組,以逗號隔開。組測試的用法將在後面文章單獨介紹。
  • invocationCount : 指定測試方法需要被調用的次數。
  • invocationTimeOut: 每一次調用的超時時間,如果invocationCount沒有指定,該參數會被忽略。應用場景可以爲測試獲取數據庫連接,超時就認定爲失敗。單位是毫秒。
  • priority : 指定測試方法的優先級,數值越低,優先級越高,將會優先與其他數值高的測試方法被調用。(注意是針對一個測試類的優先級)
  • timeout : 指定整個測試方法的超時時間。單位是毫秒。

下面我們寫一個簡單的測試類,說明@Test註解的使用以及屬性的配置方式:

package com.crazypig.testngdemo;

import org.testng.annotations.Test;

public class TestAnnotationPropertiesTest {

    @Test(priority = 1, invocationCount = 3)
    public void test1() {
        System.out.println("invoke test1");
    }

    @Test(priority = 2, invocationCount = 2)
    public void test2() {
        System.out.println("invoke test2");
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

testng.xml配置

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
  <test name="test1" >
    <classes>
       <class name="com.crazypig.testngdemo.TestAnnotationPropertiesTest" />
    </classes>
  </test>
</suite>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

運行結果:

invoke test1
invoke test1
invoke test1
invoke test2
invoke test2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

3. @Parameters 註解

@Parameters 註解用於爲測試方法傳遞參數, 用法如下所示:

package com.crazypig.testngdemo;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class AnnotationParametersTest {

    @Parameters(value = {"param1", "param2"})
    @Test
    public void test(String arg1, String arg2) {
        System.out.println("use @Parameters to fill method arguments : arg 1 = " + arg1 + ", arg2 = " + arg2);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

testng.xml配置

<test name="testAnnotationParameters">
    <parameter name="param1" value="value1"></parameter>
    <parameter name="param2" value="value2"></parameter>
    <classes>
        <class name="com.crazypig.testngdemo.AnnotationParametersTest" />
    </classes>
</test>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

運行結果:

use @Parameters to fill method arguments : arg 1 = value1, arg2 = value2
  • 1
  • 1

4. @DataProvider 註解

上面的小結提到@Parameters註解可以爲測試方法傳遞參數,但是這種方式參數值需要配置在testng.xml裏面,靈活性不高。而@DataProvider註解同樣可以爲測試方法傳遞參數值,並且,它是真正意義上的參數構造器,可以傳入多組測試數據對測試方法進行測試。被@DataProvider註解的方法,方法返回值必須爲Object[][]或者Iterator<Object[]>。例子如下所示:

package com.crazypig.testngdemo;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class AnnotationDataProviderTest {

    @DataProvider(name="testMethodDataProvider")
    public Object[][] testMethodDataProvider() {

        return new Object[][]{{"value1-1", "value2-1"}, {"value1-2", "value2-2"}, {"value1-3", "value2-3"}};

    }

    @Test(dataProvider="testMethodDataProvider")
    public void test(String arg1, String arg2) {
        System.out.println("use @DataProvider to fill method argument : arg1 = " + arg1 + " , arg2 = " + arg2);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

testng.xml配置:

<test name="testDataProvider">
  <classes>
    <class name="com.crazypig.testngdemo.AnnotationDataProviderTest" />
  </classes>
</test>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

運行結果:

use @DataProvider to fill method argument : arg1 = value1-1 , arg2 = value2-1
use @DataProvider to fill method argument : arg1 = value1-2 , arg2 = value2-2
use @DataProvider to fill method argument : arg1 = value1-3 , arg2 = value2-3
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

5. @Factory 註解

在一個方法上面打上@Factory註解,表示該方法將返回能夠被TestNG測試的測試類。利用了設計模式中的工廠模式。例子如下所示:

package com.crazypig.testngdemo;

import org.testng.annotations.Factory;

public class AnnotationFactoryTest {

    @Factory
    public Object[] getSimpleTest() {
        return new Object[]{ new SimpleTest("one"), new SimpleTest("two")};
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
package com.crazypig.testngdemo;

import org.testng.annotations.Test;

public class SimpleTest {

    private String param;

    public SimpleTest(String param) {
        this.param = param;
    }

    @Test
    public void test() {
        System.out.println("SimpleTest.param = " + param);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

testng.xml配置:

<test name="testFactory">
    <classes>
        <class name="com.crazypig.testngdemo.AnnotationFactoryTest" />
    </classes>
</test>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

運行結果:

SimpleTest.param = one
SimpleTest.param = two
  • 1
  • 2
  • 1
  • 2

6. @Listeners 註解

一般我們寫測試類不會涉及到這種類型的註解,這個註解必須定義在類、接口或者枚舉類級別。實用的Listener包括ISuiteListenerITestListenerIInvokedMethodListener,他們可以在suite級別、test級別和test method一些執行點執行一些自定義操作,如打印日誌。因爲很少使用,這裏不以例子形式給出,感興趣的可以自己研究一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章