TestNG,即Testing, Next Generation,下一代測試技術,是一套根據JUnit 和NUnit思想而構建的利用註釋來強化測試功能的一個測試框架。TestNG is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use。java
@BeforeSuite: 被此註解的方法將在全部測試運行以前運行該方法。mysql
@AfterSuite: 被此註解的方法將在全部測試運行以後運行該方法。linux
@BeforeTest: 被此註解的方法,將在測試類運行以前運行,只被執行一次。正則表達式
@AfterTest: 被此註解的方法,將在測試運行以後運行。sql
@BeforeClass: 被此註解的方法,將在當前類的第一個測試方法調用以前運行windows
@AfterClass: 被此註解的方法,將在當前類的全部測試方法調用以後運行安全
@BeforeMethod: 被此註解的方法,將在每一個測試方法調用以前運行多線程
@AfterMethod: 被此註解的方法,將在每一個測試方法調用以後運行。併發
@Test: 將類或方法標記爲測試的一部分,此標記若放在類上,則該類全部公共方法都將被做爲測試方法框架
@DataProvider: 標記一種方法來提供測試方法的數據。 註釋方法必須返回一個Object [] [],其中每一個Object []能夠被分配給測試方法的參數列表。 要從該DataProvider接收數據的@Test方法須要使用與此註釋名稱相等的dataProvider名稱
@Parameters: 描述如何將參數傳遞給@Test方法
@Factory: 將一個方法標記爲工廠,返回TestNG將被用做測試類的對象。 該方法必須返回Object []
@Listeners: 定義測試類上的偵聽器
斷言類是Assert.java,裏面有多個靜態方法被稱爲硬斷言,硬斷言就是,若是運行到折行斷言失敗,即便後面還有其餘代碼行,也不會繼續執行下去。
(1) assertTrue:判斷是否爲True。
(2) assertFalse:判斷是否爲false。
(3) assertSame:判斷引用地址是否相同。
(4) assertNotSame:判斷引用地址是否不相同。
(5) assertNull:判斷是否爲null。
(6) assertNotNull:判斷是否不爲null。
(7) assertEquals:判斷是否相等,Object類型的對象須要實現haseCode及equals方法。
(8) assertNotEquals:判斷是否不相等。
(9) assertEqualsNoOrder:判斷忽略順序是否相等
SoftAssert的特色
1) 若是一個斷言失敗,會繼續執行這個斷言下的其餘語句或者斷言
2) 也就是一個用例有多個斷言,失敗了其中一個,不影響其餘斷言的運行
3) 不要忘記調用assertAll()在該用例的最後一個斷言後面
4) 軟斷言的類,叫SoftAssert.java,這個類是須要建立實例對象,才能調用相關實例方法進行軟斷言
具體實例方法此處忽略,請參考硬斷言方法。
預期異常測試經過在@Test註解後加入預期的Exception來進行添加,範例以下所示:
@Test(expectedExceptions = ArithmeticException.class)
public void divisionWithException() {
int i = 1 / 0;
System.out.println("After division the value of i is :"+ i);
}
測試其餘異常同樣的,只須要在@Test註解後加入預期的Exception便可,假如出現了該異常,則會判斷測試經過。
有時候咱們寫的用例沒準備好,或者該次測試不想運行此用例,那麼刪掉顯然不明智,那麼就能夠經過註解@Test(enabled = false)
來將其忽略掉,此用例就不會運行了,默認是true。
「超時」表示若是單元測試花費的時間超過指定的毫秒數,那麼TestNG將會停止它並將其標記爲失敗。此項經常使用於性能測試。以下爲一個範例:
@Test(timeOut = 3000) // time in mulliseconds
public void testThisShouldPass() throws InterruptedException {
Thread.sleep(4000);
}
分組測試即爲使用group,若是你使用xml的話就是裏邊的<groups>標籤,若是是直接在class中,是經過@Test(groups="group2")這種方式來分組,並且@BeforeGroup是須要添加group名稱才能夠正確掛載到該group下的;
這個group說明能夠是在單個的測試方法上,也能夠在class上,只要具備一樣的group名稱都會在同一個group中,同時group名稱能夠有多個,相似@Test(groups = {"mysql","database"})這種
xml文件配置以下:
<suite name="Suite" parallel="false">
<test name="Test">
<groups>
<incloud name="group1"></incloud>
<incloud name="group2"></incloud>
</groups>
<classes>
<class name="com.demo.test.testng.NewTest"/>
<class name="com.demo.test.testng.TestCase1"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
測試套件是用於測試軟件程序的行爲或一組行爲的測試用例的集合。 在TestNG中,咱們沒法在測試源代碼中定義一個套件,但它能夠由一個XML文件表示,由於套件是執行的功能。 它還容許靈活配置要運行的測試。 套件能夠包含一個或多個測試,並由<suite>標記定義。<suite>是testng.xml的根標記。 它描述了一個測試套件,它又由幾個<test>部分組成。
下表列出了<suite>接受的全部定義的合法屬性。
屬性 描述
name 套件的名稱,這是一個強制屬性
verbose 運行的級別或詳細程度,級別爲0-10,其中10最詳細
parallel TestNG是否運行不一樣的線程來運行這個套件,默認爲none,其餘級別爲methods、tests、classes、instances
thread-count 若是啓用並行模式(忽略其餘方式),則爲使用的線程數
annotations 在測試中使用的註釋類型
time-out 在本測試中的全部測試方法上使用的默認超時
有時,咱們可能須要以特定順序調用測試用例中的方法,或者可能但願在方法之間共享一些數據和狀態。 TestNG支持這種依賴關係,由於它支持在測試方法之間顯式依賴的聲明。
TestNG容許指定依賴關係:
在@Test註釋中使用屬性dependsOnMethods
在@Test註釋中使用屬性dependsOnGroups
除此以外依賴還分爲hard依賴和soft依賴:
hard依賴:默認爲此依賴方式,即其全部依賴的methods或者groups必須所有pass,不然被標識依賴的類或者方法將會被略過,在報告中標識爲skip,如後面的範例所示,此爲默認的依賴方式;
soft依賴:此方式下,其依賴的方法或者組有不是所有pass也不會影響被標識依賴的類或者方法的運行,注意若是使用此方式,則依賴者和被依賴者之間必須不存在成功失敗的因果關係,不然會致使用例失敗。此方法在註解中須要加入alwaysRun=true便可,如@Test(dependsOnMethods= {"TestNgLearn1"}, alwaysRun=true);
在TestNG中,咱們使用dependOnMethods和dependsOnGroups來實現依賴測試。 且這兩個都支持正則表達式,以下面所示:
@Test(groups = { "init" })
public void serverStartedOk() {}
@Test(groups = { "init" })
public void initEnvironment() {}
@Test(dependsOnGroups = { "init.*" })
public void method1() {}
TestNG中的另外一個有趣的功能是參數化測試。 在大多數狀況下,您會遇到業務邏輯須要大量測試的場景。 參數化測試容許開發人員使用不一樣的值一次又一次地運行相同的測試。
TestNG能夠經過兩種不一樣的方式將參數直接傳遞給測試方法:
使用testng.xml
使用數據提供者
下面分別介紹兩種傳參方式:
範例代碼以下:
public class TestCase1 {
@Parameters({"param1", "param2"})
public void TestNgLearn1(String param1, int param2) {
System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);
Assert.assertFalse(false);
}
}
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
<test name="Test">
<parameter name="param1" value="1011111" />
<parameter name="param2" value="10" />
<classes>
<class name="com.demo.test.testng.TestCase1"/>
</classes>
</test>
</suite>
@DataProvider
傳遞參數此處須要注意,傳參的類型必需要一致,且帶有@DataProvider
註解的函數返回的必然是Object[][]
,此處須要注意。
示例代碼以下:
public class TestCase1 {
@DataProvider(name = "provideNumbers")
public Object[][] provideData() {
return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
}
@Test(dataProvider = "provideNumbers")
public void TestNgLearn1(int param1, int param2) {
System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);
Assert.assertFalse(false);
}
以下分別講解各個標籤:
testNG.xml文件的最外層標籤即suite,即測試套件,其下能夠有多個<test>和<groups>,其有幾個能夠添加的屬性在第十節的分suite測試中有作說明,這裏作下詳細說明:
(1)、name屬性
此屬性屬於必需要有的,值能夠自行設定,此名字會在testNG的報告中看到;
(2)、verbose屬性
此屬性爲指定testNG報告的詳細程度,從0開始到10,其中10爲最詳細,默認生成的xml此屬性值爲1;
(3)、parallel屬性
此屬性是指代運行方式,默認爲none,即串行運行方式;並行執行方法包括以下幾種,下面作分別說明:
a.methods:方法層級,若爲此值,則該suite下全部的測試方法都將進行多線程,即測試用例級別的多線程。若是用例之間有依賴,則執行順序會按照設定的依賴來運行;
<suite name="My suite" parallel="methods" thread-count="5">
b.tests:TestNG將在同一線程中運行相同的<Test>標籤中的全部方法,每一個<test>標籤都將處於一個單獨的線程中,這容許您將不是線程安全的全部類分組在同一個<test>中,並保證它們都將在同一個線程中運行,同時利用TestNG使用盡量多的線程運行測試。
<suite name="My suite" parallel="tests" thread-count="5">
c.classes:類級別併發,即TestNG會將該suite下每一個class都將在單獨的線程中運行,同一個class下的全部用例都將在同一個線程中運行;
<suite name="My suite" parallel="classes" thread-count="5">
d.instances:實例級別,即TestNG將在同一線程中運行同一實例中的全部方法,兩個不一樣實例上的兩個方法將在不一樣的線程中運行。
<suite name="My suite" parallel="instances" thread-count="5">
(4)、thread-count屬性
此屬性用於指定線程數,按照須要輸入,須要parallel參數非none時才能夠添加;
(5)、annotations屬性
此項爲註解的級別,爲methods級別和class級別,通常不用設置;
(6)、time-out屬性
此屬性用於指定超時時間,該suite下全部的用例的超時時間;
(7)、group-by-instances屬性
此項用於那些有依賴的方法,且被依賴的對象有多個重載對象,由於若是是依賴方法,且該方法有多個重載方法,則默認是會將全部重載方法都跑完再運行被依賴方法,但有時候咱們不想這樣,則將此項設置爲true便可;
(8)、preserve-order屬性
值可輸入true或者false,若是爲true,則用例執行會按照在xml中的順序執行,不然會亂序執行,不添加此屬性的話默認是按順序執行的;
此標籤無特別意義,其下能夠包括多個標籤,如groups、classes等,以下介紹下幾種書寫方式:
選擇一個包中的所有測試腳本(包含子包)
<test name = "allTestsInAPackage" >
<packages>
<package name = "whole.path.to.package.* />
</packages>
</test>
選擇一個類中的所有測試腳本
<test name = "allTestsInAClass" >
<classes>
<class name="whole.path.to.package.className />
</classes>
</test>
選擇一個類中的部分測試腳本
<test name = "aFewTestsFromAClass" >
<classes>
<class name="whole.path.to.package.className >
<methods>
<include name = "firstMethod" />
<include name = "secondMethod" />
<include name = "thirdMethod" />
</methods>
</class>
</classes>
</test>
選擇一個包中的某些組
<test name = "includedGroupsInAPackage" >
<groups>
<run>
<include name = "includedGroup" />
</run>
</groups>
<packages>
<package name = "whole.path.to.package.* />
</packages>
</test>
排除一個包中的某些組
<test name = "excludedGroupsInAPackage" >
<groups>
<run>
<exclude name = "excludedGroup" />
</run>
</groups>
<packages>
<package name = "whole.path.to.package.* />
</packages>
</test>
其能夠附帶的屬性有以下幾種,下面對各個屬性作單獨說明:
(1)、name屬性
此屬性屬於必需要有的,值能夠自行設定,此名字會在testNG的報告中看到;
(2)、verbose屬性
此屬性爲指定testNG報告的詳細程度,從0開始到10,其中10爲最詳細,默認生成的xml此屬性值爲1
(3)、threadPoolSize屬性
該屬性指定此test的線程池大小,爲數字;
@Test(threadPoolSize = 3, invocationCount = 10, timeOut = 10000)
public void testServer() {
}
(4)、invocationCount屬性
該屬性指定此test的運行次數,爲數字,範例如上面的代碼所示;
(5)、time-out屬性
此屬性用於指定超時時間,該suite下全部的用例的超時時間,範例如上面的代碼所示;
(6)、group-by-instances屬性
此項用於那些有依賴的方法,且被依賴的對象有多個重載對象,由於若是是依賴方法,且該方法有多個重載方法,則默認是會將全部重載方法都跑完再運行被依賴方法,但有時候咱們不想這樣,則將此項設置爲true便可;
<suite name="Factory" group-by-instances="true">
(7)、preserve-order屬性
值可輸入true或者false,若是爲true,則用例執行會按照在xml中的順序執行,不然會亂序執行,不添加此屬性的話默認是按順序執行的;
此標籤必然是在<test>標籤下的,用於標識那些組會被用於測試或者被排除在測試以外,其同級必然要包含一個<classes>標籤或者<pakages>標籤,用於指定groups來自於哪些包或者類;
以下即爲包含一個group,排除一個group的例子:
<groups>
<run>
<include name = "includedGroupName" />
<exclude name = "excludedGroupName" />
</run>
</groups>
高級應用:
<test name="Regression1">
<groups>
<define name="functest">
<include name="windows"/>
<include name="linux"/>
</define>
<define name="all">
<include name="functest"/>
<include name="checkintest"/>
</define>
<run>
<include name="all"/>
</run>
</groups>
<classes>
<class name="test.sample.Test1"/>
</classes>
</test>
其餘的話就是測試腳本的選擇了,有三種方式:
選擇一個包
<packages>
<package name = "packageName" />
</packages>
選擇一個類
<classes>
<class name = "className" />
</classes>
選擇一個方法
<classes>
<class name = "className" />
<methods>
<include name = "methodName" />
</methods>
</class>
</classes>
這裏也支持正則表達式,例如:
<test name="Test1">
<classes>
<class name="example1.Test1">
<methods>
<include name=".*enabledTestMethod.*"/>
<exclude name=".*brokenTestMethod.*"/>
</methods>
</class>
</classes>
</test>