目錄
(一)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í)之路—注解詳述之忽略測試
(八)TestNG學(xué)習(xí)之路—注解詳述之并發(fā)
(九)TestNG學(xué)習(xí)之路—失敗測試重跑
(十)TestNG學(xué)習(xí)之路—編碼執(zhí)行TestNG
(十一)TestNG學(xué)習(xí)之路—BeanShell高級用法
(十二)TestNG學(xué)習(xí)之路—注解轉(zhuǎn)換器
(十三)TestNG學(xué)習(xí)之路—方法攔截器
(十四)TestNG學(xué)習(xí)之路—TestNG監(jiān)聽器
(十五)TestNG學(xué)習(xí)之路—依賴注入
(十六)TestNG學(xué)習(xí)之路—測試報告
(十七)基于TestNG+Rest Assured+Allure的接口自動化測試框架
前言
TestNG提供的諸多注解中穿肄,用得最頻繁的估計是@Test了,該篇文章將對@Test注解進(jìn)行詳述际看。
@Test詳述
- 《TestNG學(xué)習(xí)之路—TestNG.xml/YAML》提到了allow-return-values屬性:如果設(shè)置為false咸产,被@Test注解且有return的方法將被忽略執(zhí)行。
import org.testng.annotations.*;
public class TestNGHelloWorld1 {
@BeforeTest
public void bfTest(){
System.out.println("TestNGHelloWorld1 beforTest!");
}
@Test()
public String helloWorldTest1(){
System.out.println("TestNGHelloWorld1 Test1!");
return "@Test return!";
}
@AfterTest
public void AfTest(){
System.out.println("TestNGHelloWorld1 AfterTest!");
}
}
如下所示仲闽,testng.xml配置allow-return-values為false(默認(rèn)為false)脑溢,執(zhí)行測試會忽略@Test注解的helloWorldTest1方法。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" allow-return-values="false">
<test verbose="2" preserve-order="true" name="D:/IntelliJ_IDEA_workspace/TestNG/src/test/resources">
<classes>
<class name="TestNGHelloWorld1"/>
</classes>
</test>
</suite>
輸出結(jié)果為:
TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 AfterTest!
===============================================
Default Suite
Total tests run: 0, Failures: 0, Skips: 0
===============================================
- description屬性
描述@Test赖欣,在測試報告體現(xiàn)屑彻。
@Test(description = "test")
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
}
- enabled屬性
設(shè)置為false,執(zhí)行測試會忽略@Test注解的helloWorldTest1方法畏鼓。
@Test(enabled = false)
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
}
- groups屬性
對測試方法進(jìn)行分組酱酬,可在類級別或方法級別添加組,類級別分組云矫,表示類里面的所有方法都屬于該分組膳沽,如下所示。
import org.testng.annotations.*;
@Test(groups = "test")
public class TestNGHelloWorld1 {
@BeforeTest
public void bfTest() {
System.out.println("TestNGHelloWorld1 beforTest!");
}
@Test(groups = {"test1","test2"})
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
}
@Test(groups = {"test3"})
public void helloWorldTest2() {
System.out.println("TestNGHelloWorld1 Test2!");
}
@AfterTest
public void AfTest() {
System.out.println("TestNGHelloWorld1 AfterTest!");
}
}
運(yùn)行分組test分組,但不運(yùn)行test1分組挑社。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="D:/IntelliJ_IDEA_workspace/TestNG/src/test/resources">
<groups>
<run>
<include name="test"/>
<exclude name="test1"/>
</run>
</groups>
<classes>
<class name="TestNGHelloWorld1"/>
</classes>
</test>
</suite>
輸出結(jié)果:
TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 Test2!
TestNGHelloWorld1 AfterTest!
===============================================
All Test Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
xml配置組名稱等也支持正則表達(dá)式陨界,開發(fā)/測試人員可更靈活的配置測試,例如:
<groups>
<run>
<!--匹配以test開始的所有組-->
<include name="test.*"/>
<exclude name="test1"/>
</run>
</groups>
<classes>
<class name="TestNGHelloWorld1">
<methods>
<!--匹配包含Test2串的方法-->
<include name=".*Test2.*"/>
</methods>
</class>
</classes>
- dependsOnGroups屬性
定義組之間的依賴關(guān)系痛阻,可使用正則表達(dá)式作為參數(shù)菌瘪。
import org.testng.Assert;
import org.testng.annotations.*;
public class TestNGHelloWorld1 {
@BeforeTest
public void bfTest() {
System.out.println("TestNGHelloWorld1 beforTest!");
}
@Test(groups = {"test1"})
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
Assert.assertEquals("1","2");
}
//test3依賴于test1組,如果test1組執(zhí)行失敗阱当,則test3跳過測試
@Test(groups = {"test3"},dependsOnGroups = "test1")
public void helloWorldTest2() {
System.out.println("TestNGHelloWorld1 Test2!");
}
@AfterTest
public void AfTest() {
System.out.println("TestNGHelloWorld1 AfterTest!");
}
}
執(zhí)行結(jié)果:
TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 Test1!
java.lang.AssertionError: expected [2] but found [1]
Expected :2
Actual :1
<Click to see difference>
at org.testng.Assert.fail(Assert.java:93)
at org.testng.Assert.failNotEquals(Assert.java:512)
at org.testng.Assert.assertEqualsImpl(Assert.java:134)
at org.testng.Assert.assertEquals(Assert.java:115)
at org.testng.Assert.assertEquals(Assert.java:189)
at org.testng.Assert.assertEquals(Assert.java:199)
at TestNGHelloWorld1.helloWorldTest1(TestNGHelloWorld1.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:661)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:744)
at org.testng.TestRunner.run(TestRunner.java:602)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
at org.testng.SuiteRunner.run(SuiteRunner.java:289)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
at org.testng.TestNG.runSuites(TestNG.java:1144)
at org.testng.TestNG.run(TestNG.java:1115)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Test ignored.
TestNGHelloWorld1 AfterTest!
===============================================
All Test Suite
Total tests run: 2, Failures: 1, Skips: 1
===============================================
- dependsOnMethods屬性
定義方法之間的依賴關(guān)系俏扩,與dependsOnGroups用法類似”滋恚可使用正則表達(dá)式作為參數(shù)录淡。另外,如果依賴于一個碰巧有多個重載版本的方法油坝,那么會調(diào)用所有重載的方法嫉戚。 - timeout屬性
設(shè)定超時時間(單位為ms),如果執(zhí)行測試超過該設(shè)定時間澈圈,則當(dāng)做失敗處理彬檀。
@Test(timeOut = 2000)
public void helloWorldTest2() throws InterruptedException {
Thread.sleep(3000);
System.out.println("TestNGHelloWorld1 Test2!");
}
- invocationTimeOut屬性
該屬性和invocationCount結(jié)合使用才會工作,耗時值不能超過設(shè)置的最大毫秒數(shù)瞬女。
@Test(invocationCount = 5, invocationTimeOut = 4000)
public void helloWorldTest3() throws InterruptedException{
Thread.sleep(1000);
System.out.println("lsss");
}
- invocationCount屬性
表示執(zhí)行的次數(shù)窍帝。
@Test(threadPoolSize = 3,invocationCount = 2,timeOut = 2000)
public void helloWorldTest2() throws InterruptedException {
Thread.sleep(3000);
System.out.println("TestNGHelloWorld1 Test2!");
}
- threadPoolSize屬性
表示線程池的內(nèi)線程的個數(shù)。
@Test(threadPoolSize = 3,invocationCount = 2,timeOut = 2000)
public void helloWorldTest2() throws InterruptedException {
Thread.sleep(3000);
System.out.println("TestNGHelloWorld1 Test2!");
}
- successPercentage屬性
當(dāng)前方法執(zhí)行所期望的success的百分比诽偷。如下所示盯桦,執(zhí)行10次,如果成功9次渤刃,則認(rèn)為測試通過拥峦。
@Test(invocationCount = 10,successPercentage = 9)
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
Assert.assertEquals("1","1");
}
- dataProvider屬性
結(jié)合@DataProvider使用,后續(xù)文章詳述卖子。 - dataProviderClass屬性
結(jié)合@DataProvider使用略号,后續(xù)文章詳述。 - alwaysRun屬性
如果為true洋闽,則該測試方法依然會被運(yùn)行即使其所依賴的方法執(zhí)行失敗玄柠。為false的話,則該測試方法會被skip如果其所依賴的方法執(zhí)行失敗诫舅。
import org.testng.Assert;
import org.testng.annotations.*;
public class TestNGHelloWorld1 {
@BeforeTest
public void bfTest() {
System.out.println("TestNGHelloWorld1 beforTest!");
}
@Test()
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
Assert.assertEquals("2", "1");
}
@Test(dependsOnMethods = "helloWorldTest1",alwaysRun = true)
public void helloWorldTest2() throws InterruptedException {
System.out.println("TestNGHelloWorld1 Test2!");
}
@AfterTest
public void AfTest() {
System.out.println("TestNGHelloWorld1 AfterTest!");
}
}
執(zhí)行結(jié)果:
TestNGHelloWorld1 beforTest!
TestNGHelloWorld1 Test1!
java.lang.AssertionError: expected [1] but found [2]
Expected :1
Actual :2
<Click to see difference>
at org.testng.Assert.fail(Assert.java:93)
at org.testng.Assert.failNotEquals(Assert.java:512)
at org.testng.Assert.assertEqualsImpl(Assert.java:134)
at org.testng.Assert.assertEquals(Assert.java:115)
at org.testng.Assert.assertEquals(Assert.java:189)
at org.testng.Assert.assertEquals(Assert.java:199)
at TestNGHelloWorld1.helloWorldTest1(TestNGHelloWorld1.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:661)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:744)
at org.testng.TestRunner.run(TestRunner.java:602)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
at org.testng.SuiteRunner.run(SuiteRunner.java:289)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
at org.testng.TestNG.runSuites(TestNG.java:1144)
at org.testng.TestNG.run(TestNG.java:1115)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
TestNGHelloWorld1 Test2!
TestNGHelloWorld1 AfterTest!
===============================================
Default Suite
Total tests run: 2, Failures: 1, Skips: 0
===============================================
- expectedExceptions屬性
屬性expectedExceptions是一組類羽利,包含了這個測試方法中預(yù)期會拋出的異常列表。如果沒有拋出異常刊懈,或拋出的異常不再該屬性的類表中这弧,那么TestNG就會認(rèn)為這個測試方法失敗了娃闲。以下測試執(zhí)行通過。
@Test(expectedExceptions = ArithmeticException.class)
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
int c = 1/0;
Assert.assertEquals("1", "1");
}
- expectedExceptionsMessageRegExp屬性
異常信息正則表達(dá)式匾浪。以下測試執(zhí)行通過皇帮。
@Test(expectedExceptions = ArithmeticException.class,expectedExceptionsMessageRegExp = ".*zero")
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
int c = 1/0;
Assert.assertEquals("1", "1");
}
- suiteName屬性
測試套件名稱。 - testName屬性
測試名稱蛋辈,跟description屬性作用類似属拾。 - singleThreaded屬性
如果設(shè)置為true,那么這個測試類中的所有方法都保證在同一個線程中運(yùn)行冷溶,即使測試當(dāng)前使用parallel="methods"運(yùn)行渐白。這個屬性只能在類級別使用,如果在方法級別使用逞频,它將被忽略礼预。 - retryAnalyzer屬性
TestNG重試機(jī)制,后續(xù)文章詳解虏劲。 - skipFailedInvocations屬性
是否跳過失敗的調(diào)用,如果不跳過褒颈,可能會導(dǎo)致測試用例的死鎖柒巫。 - ignoreMissingDependencies屬性
如果為true,找不到依賴也繼續(xù)執(zhí)行谷丸。
import org.testng.Assert;
import org.testng.annotations.*;
public class TestNGHelloWorld1 {
@BeforeTest
public void bfTest() {
System.out.println("TestNGHelloWorld1 beforTest!");
}
@Test(expectedExceptions = ArithmeticException.class, expectedExceptionsMessageRegExp = ".*zero")
public void helloWorldTest1() {
System.out.println("TestNGHelloWorld1 Test1!");
int c = 1 / 0;
Assert.assertEquals("1", "1");
}
@Test(dependsOnGroups = "test",ignoreMissingDependencies = true)
public void helloWorldTest2() {
Assert.assertEquals("1", "1");
System.out.println("TestNGHelloWorld1 Test2!");
}
@AfterTest
public void AfTest() {
System.out.println("TestNGHelloWorld1 AfterTest!");
}
}
- priority屬性
標(biāo)注測試方法的優(yōu)先級堡掏。較低的優(yōu)先級將優(yōu)先執(zhí)行。