目錄
(一)TestNG學(xué)習(xí)之路—HelloWorld入門
(二)TestNG學(xué)習(xí)之路—注解及屬性概覽
(三)TestNG學(xué)習(xí)之路—TestNG.xml/YAML
(四)TestNG學(xué)習(xí)之路—注解詳述之@Test
(五)TestNG學(xué)習(xí)之路—注解詳述之參數(shù)化
(六)TestNG學(xué)習(xí)之路—注解詳述之@Factory
(七)TestNG學(xué)習(xí)之路—注解詳述之忽略測(cè)試
(八)TestNG學(xué)習(xí)之路—注解詳述之并發(fā)
(九)TestNG學(xué)習(xí)之路—失敗測(cè)試重跑
(十)TestNG學(xué)習(xí)之路—編碼執(zhí)行TestNG
(十一)TestNG學(xué)習(xí)之路—BeanShell高級(jí)用法
(十二)TestNG學(xué)習(xí)之路—注解轉(zhuǎn)換器
(十三)TestNG學(xué)習(xí)之路—方法攔截器
(十四)TestNG學(xué)習(xí)之路—TestNG監(jiān)聽器
(十五)TestNG學(xué)習(xí)之路—依賴注入
(十六)TestNG學(xué)習(xí)之路—測(cè)試報(bào)告
(十七)基于TestNG+Rest Assured+Allure的接口自動(dòng)化測(cè)試框架
前言
TestNG提供了諸多注解,允許開發(fā)/測(cè)試人員靈活地組織強(qiáng)大的測(cè)試用例。
注解概覽
| 注解/屬性 | 描述 |
|---|---|
| @BeforeSuite | 帶@BeforeSuite注釋的方法將在本套件中所有測(cè)試運(yùn)行之前運(yùn)行。 |
| @AfterSuite | 帶@AfterSuite注釋的方法將在本套件中所有測(cè)試運(yùn)行之后運(yùn)行。 |
| @BeforeTest | @BeforeTest注解的方法將在testNG.xml文件test標(biāo)簽內(nèi)的所有類方法運(yùn)行前執(zhí)行。 |
| @AfterTest | @AfterTest注解的方法將在testNG.xml文件test標(biāo)簽內(nèi)的所有類方法運(yùn)行后執(zhí)行。 |
| @BeforeGroups | 被@BeforeGroups注解的方法會(huì)在組列表中之前被調(diào)用。 |
| @AfterGroups | 被@AfterGroups注解的方法會(huì)在組列表中之后被調(diào)用。 |
| @BeforeClass | 在調(diào)用當(dāng)前類中的第一個(gè)測(cè)試方法之前,將運(yùn)行帶@BeforeClass注釋的方法。 |
| @AfterClass | 在運(yùn)行當(dāng)前類中的所有測(cè)試方法之后,將運(yùn)行帶@AfterClass注釋的方法。 |
| @BeforeMethod | @BeforeMethod注釋的方法將在每個(gè)測(cè)試方法之前運(yùn)行。 |
| @AfterMethod | @AfterMethod注釋的方法將在每個(gè)測(cè)試方法之后運(yùn)行。 |
| alwaysRun | 對(duì)于在方法之前的調(diào)用(BeforeSuite,...除了beforeGroups),若為true,這個(gè)配置方法無視其所屬的組而運(yùn)行.對(duì)于在方法之后的調(diào)用(afterSuite, afterClass, ...),若為true, 這個(gè)配置方法會(huì)運(yùn)行,即使其之前一個(gè)或者多個(gè)被調(diào)用的方法失敗或者被跳過。 |
| dependsOnGroups | 方法依賴的組列表。 |
| dependsOnMethods | 方法依賴的方法列表。 |
| enabled | 是否執(zhí)行注解的測(cè)試。 |
| groups | 類/方法所屬的組列表。 |
| inheritGroups | 默認(rèn)是true,則此方法會(huì)從屬于在類級(jí)由@Test注解中所指定的組。舉例如下: @Test(groups = "Tomandy") public class TestNGHelloWorld { @BeforeClass(inheritGroups = false) //如果xml文件配置按Tomandy組執(zhí)行的話,@BeforeClass注解的方法不會(huì)被執(zhí)行 public void setUp(){ System.out.println("setUp!"); } @Test(groups = "Tom") public void helloWorld(){ System.out.println("My first TestNG testCase!"); } } |
| onlyForGroups | 只適用于@BeforeMethod和@AfterMethod。如果指定了,那么只有當(dāng)相應(yīng)的測(cè)試方法屬于所列的組之一時(shí),才會(huì)調(diào)用這個(gè)setup/teardown方法。 |
| @DataProvider | 將方法標(biāo)記為測(cè)試方法提供數(shù)據(jù)。帶@DataProvider注釋的方法必須返回一個(gè)對(duì)象[][]。想要從這個(gè)DataProvider接收數(shù)據(jù)的@Test方法需要使用dataProvider屬性,此屬性值必須與@DataProvider注解中的名字相同。 @DataProvider(name = "casesProvider") @Test(dataProvider = "casesProvider") |
| name | dataProvider的名稱。如果沒有提供,默認(rèn)為@DataProvider標(biāo)注方法的名稱。 |
| parallel | 默認(rèn)為false,如果為true,將并行執(zhí)行測(cè)試,可大大提高用例執(zhí)行效率。 |
| @Factory | 將方法標(biāo)記為工廠,該工廠返回將被TestNG用作測(cè)試類的對(duì)象。方法必須返回對(duì)象[]。 |
| @Listeners | 定義監(jiān)聽器。 |
| value | 繼承org.testng.ITestNGListener的classe數(shù)組。繼承IAnnotationTransformer和IAnnotationTransformer2的類不允許使用@Listeners,可通過testNG.xml定義。 |
| @Parameters | 給一個(gè)@Test方法傳參。 |
| value | 方法參數(shù)的變量列表。 |
| @Test | 把一個(gè)類或者方法標(biāo)記為測(cè)試的一部分。 |
| alwaysRun | 如果為true,則該測(cè)試方法依然會(huì)被運(yùn)行即使其所依賴的方法執(zhí)行失敗。為false的話,則該測(cè)試方法會(huì)被skip如果其所依賴的方法執(zhí)行失敗。 |
| dataProvider | 此測(cè)試方法的dataProvider的名稱。 |
| dataProviderClass | 查找dataProvider的類。如果沒有指定,則在當(dāng)前測(cè)試方法所在的類或者它的基類中去查。如果指定了該屬性,則@DataProvider注解的方法需在指定的類上保持靜態(tài)(static),舉例如下: @DataProvider(name = "casesProvider") public static Object[][] caseProvider(){} -------------------------------------------------------- @Test(dataProvider = "casesProvider", dataProviderClass = CasesDataProvider.class) public void runCases(){} |
| dependsOnGroups | 方法依賴的組列表。 |
| dependsOnMethods | 方法依賴的方法列表。 |
| description | 方法描述。 |
| enabled | 是否執(zhí)行@Test()注解的測(cè)試。 |
| expectedExceptions | 期望測(cè)試方法拋出的異常列表。如果沒有異?;蛟诖肆斜碇袥]有異常,則此測(cè)試將被標(biāo)記為失敗。 |
| groups | 類/方法所屬的組列表。 |
| invocationCount | 調(diào)用方法的次數(shù)。 |
| invocationTimeOut | 當(dāng)前測(cè)試中所有調(diào)用累計(jì)時(shí)間的最大毫秒數(shù)。如果invocationCount屬性沒有指定,那么此屬性會(huì)被忽略。 |
| priority | 標(biāo)注測(cè)試方法的優(yōu)先級(jí)。較低的優(yōu)先級(jí)將優(yōu)先執(zhí)行。 |
| successPercentage | 當(dāng)前方法執(zhí)行所期望的成功率。 |
| singleThreaded | 如果設(shè)置為true,那么這個(gè)測(cè)試類中的所有方法都保證在同一個(gè)線程中運(yùn)行,即使測(cè)試當(dāng)前使用parallel="methods"運(yùn)行。這個(gè)屬性只能在類級(jí)別使用,如果在方法級(jí)別使用,它將被忽略 |
| timeOut | 當(dāng)前測(cè)試需要的最大毫秒數(shù),超過該時(shí)間則執(zhí)行失敗。 |
| threadPoolSize | 此方法的線程池的大小。該方法將根據(jù)invocationCount值,啟用多個(gè)線程調(diào)用。如果沒有指定invocationCount,則忽略此屬性。 |
舉例說明
1、@BeforeXXX @AfterXXX
根據(jù)testng.xml文件配置,可了解測(cè)試級(jí)別為:suite -> test -> class -> method。test指的是testng.xml中的test 標(biāo)簽,而不是測(cè)試類里的一個(gè) @Test。測(cè)試類里的@Test實(shí)際上對(duì)應(yīng)的是method。所以在使用 @BeforeSuite、 @BeforeTest、 @BeforeClass、 @BeforeMethod這些標(biāo)簽的時(shí)候,它們的實(shí)際執(zhí)行順序也是按照上述級(jí)別來的。
- 關(guān)于上述的注解,舉例如下:
import org.testng.annotations.*;
@Test(groups = "Tomandy")
public class TestNGHelloWorld {
@BeforeSuite(groups = "bfSuite")
public void bfSuite(){
System.out.println("TestNGHelloWorld BeforeSuite!");
}
@BeforeClass(enabled = false) //不可執(zhí)行
public void bfClass(){
System.out.println("TestNGHelloWorld BeforeClass!");
}
@BeforeTest(dependsOnGroups = "bfSuite") //依賴bfSuite組
public void bfTest(){
System.out.println("TestNGHelloWorld BeforeTest!");
}
@BeforeGroups(groups = {"Tom"})
public void bfGroups(){
System.out.println("TestNGHelloWorld BeforeGroups!");
}
@BeforeMethod(alwaysRun = true,dependsOnGroups = "bfSuite")//依賴bfSuite組,alwaysRun
public void bfMethod(){
System.out.println("TestNGHelloWorld BeforeMethod!");
}
@Test(groups = "Tom")
public void helloWorldTest(){
System.out.println("TestNGHelloWorld Test!");
}
@AfterSuite
public void afSuite(){
System.out.println("TestNGHelloWorld AfterSuite!");
}
@AfterClass()
public void afClass(){
System.out.println("TestNGHelloWorld AfterClass!");
}
@AfterTest
public void afTest(){
System.out.println("TestNGHelloWorld AfterTest!");
}
@AfterGroups(groups = "Tom")
public void afGroups(){
System.out.println("TestNGHelloWorld AfterGroups!");
}
@AfterMethod
public void afMethod(){
System.out.println("TestNGHelloWorld AfterMethod!");
}
}
testNG.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Default Suite"> <!-- 可定義測(cè)試套件名稱 -->
<test name="TestNG">
<groups>
<run>
<include name="Tomandy"/>
</run>
</groups>
<classes >
<class name="TestNGHelloWorld"/>
</classes >
</test> <!-- TestNG -->
</suite> <!-- Default Suite -->
運(yùn)行結(jié)果如下:
TestNGHelloWorld BeforeSuite!
TestNGHelloWorld BeforeTest!
TestNGHelloWorld BeforeGroups!
TestNGHelloWorld BeforeMethod!
TestNGHelloWorld Test!
TestNGHelloWorld AfterMethod!
TestNGHelloWorld AfterGroups!
TestNGHelloWorld AfterClass!
TestNGHelloWorld AfterTest!
TestNGHelloWorld AfterSuite!
===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
- 超類上的注解,子類也將得到繼承。在這種情況下,TestNG保證“@Before”方法按照繼承順序執(zhí)行(首先是最高的超類,然后向下繼承鏈),以及“@After”方法按照相反的順序執(zhí)行(向上繼承鏈)。
父類:
import org.testng.annotations.*;
public class Car {
@BeforeClass
public void beforeClass() {
System.out.println("Car BeforeClass");
}
@Test
public void carTest() {
System.out.println("Car Test");
}
@AfterClass
public void afterClass() {
System.out.println("Car AfterClass");
}
}
子類:
import org.testng.annotations.*;
public class BMW extends Car{
@Test
public void BMWTest() {
System.out.println("BMW Test");
}
@AfterClass
public void afterClass() {
System.out.println("BMW AfterClass");
}
}
運(yùn)行子類輸出如下:
Car BeforeClass
BMW Test
Car Test
BMW AfterClass
===============================================
Default Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
由于beforeClass方法未在子類實(shí)現(xiàn),因此是子類調(diào)用父類中的beforeClass方法,AfterClass和Test也是一樣,因此,一些公共操作,可以統(tǒng)一在父類中封裝實(shí)現(xiàn),子類只實(shí)現(xiàn)各自不同的方法。
2、@DataProvider @Factory @Listeners @Parameters @Test
該部分注解后續(xù)文章再做詳述。