1、常用注解
注解 | 描述 |
---|---|
@BeforeSuite | 在该套件的所有测试都运行在注释的方法之前,仅运行一次 |
@AfterSuite | 在该套件的所有测试都运行在注释方法之后,仅运行一次 |
@BeforeClass | 在调用当前类的第一个测试方法之前运行,注释方法仅运行一次 |
@AfterClass | 在调用当前类的第一个测试方法之后运行,注释方法仅运行一次 |
@BeforeTest | 注释的方法将在属于test标签内的类的所有测试方法运行之前运行 |
@AfterTest | 注释的方法将在属于test标签内的类的所有测试方法运行之后运行 |
@BeforeGroups | 配置方法将在之前运行组列表。 此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行 |
@AfterGroups | 此配置方法将在之后运行组列表。该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行 |
@BeforeMethod | 注释方法将在每个测试方法之前运行 |
@AfterMethod | 注释方法将在每个测试方法之后运行 |
@DataProvider | 标记一种方法来提供测试方法的数据。 注释方法必须返回一个Object [] [] ,其中每个Object [] 可以被分配给测试方法的参数列表。 要从该DataProvider 接收数据的@Test 方法需要使用与此注释名称相等的dataProvider 名称 |
@Factory | 将一个方法标记为工厂,返回TestNG 将被用作测试类的对象。 该方法必须返回Object [] |
@Listeners | 定义测试类上的侦听器 |
@Parameters | 描述如何将参数传递给@Test 方法 |
@Test | 将类或方法标记为测试的一部分,此标记若放在类上,则该类所有公共方法都将被作为测试方法 |
@BeforeSuite: The annotated method will be run before all tests in this suite have run.
@AfterSuite: The annotated method will be run after all tests in this suite have run.
@BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
@AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the <test> tag have run.
@BeforeGroups: The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked.
@AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked.
@BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
@AfterClass: The annotated method will be run after all the test methods in the current class have been run.
@BeforeMethod: The annotated method will be run before each test method.
@AfterMethod: The annotated method will be run after each test method.
案例如下:
package com.apiAutoTest.testngPractice; import org.testng.annotations.*; public class TestAnnotation { @Test(groups = "group1") public void testCase1(){ System.out.println("testCase1 in group1"); } @Test(groups = "group1") public void testCase2(){ System.out.println("testCase2 in group1"); } @Test(groups = "group2") public void testCase3(){ System.out.println("testCase3 in group2"); } @BeforeMethod public void beforeMethod(){ System.out.println("beforeMethod --在每个测试方法之前运行"); } @AfterMethod public void afterMethod(){ System.out.println("afterMethod --在每个测试方法之后运行"); } @BeforeClass public void beforeClass(){ System.out.println("beforeClass--在类之前运行"); } @AfterClass public void afterClass(){ System.out.println("afterClass--在类之后运行"); } @BeforeSuite public void beforeSuite(){ System.out.println("BeforeSuite测试套件之前"); } @AfterSuite public void afterSuite(){ System.out.println("AfterSuite测试套件之后"); } @BeforeTest public void beforeTest() { System.out.println("beforeTest"); } @AfterTest public void afterTest() { System.out.println("afterTest"); } //只对group1有效,即testCase1和testCase2 @BeforeGroups(groups="group1") public void beforeGroups() { System.out.println("beforeGroups"); } //只对group1有效,即testCase1和testCase2 @AfterGroups(groups="group1") public void afterGroups() { System.out.println("afterGroups"); } }
运行结果
BeforeSuite测试套件之前 beforeTest beforeClass--在类之前运行 beforeGroups beforeMethod --在每个测试方法之前运行 testCase1 in group1 afterMethod --在每个测试方法之后运行 beforeMethod --在每个测试方法之前运行 testCase2 in group1 afterMethod --在每个测试方法之后运行 afterGroups beforeMethod --在每个测试方法之前运行 testCase3 in group2 afterMethod --在每个测试方法之后运行 afterClass--在类之后运行 afterTest AfterSuite测试套件之后 =============================================== Default Suite Total tests run: 3, Failures: 0, Skips: 0 =============================================== Process finished with exit code 0
2、testng断言
testng的Assert类中方提供了很多断言方法
import org.testng.Assert;
常用的方法举例:
1.Assert.assertEquals()方法,用来查看对象中存的值是否是期待的值,与字符串比较中使用的equals()方法类似;
2.assertFalse()和assertTrue()方法,用来查看变量是是否为false或true,如果assertFalse()查看的变量的值是false则测试成功,如果是true则失败,assertTrue()与之相反。
3.assertSame()和assertNotSame()方法,用来比较两个对象的引用是否相等和不相等,类似于通过“==”和“!=”比较两个对象;
4.assertNull()和assertNotNull()方法,用来查看对象是否为空和不为空。
3、忽略测试
加上@Test(enabled = false)之后,该用例不再执行
package com.apiAutoTest.testngPractice; import org.testng.annotations.Test; public class IgnoreTest { @Test public void ignore1(){ System.out.println("ignore方法1"); } //忽略测试 @Test(enabled = false) public void ignore2(){ System.out.println("ignore方法2"); } @Test(enabled = true) public void ignore3(){ System.out.println("ignore方法3"); } }
执行结果
ignore方法1 ignore方法3 =============================================== Default Suite Total tests run: 2, Failures: 0, Skips: 0 ===============================================
4、分组测试
1、在method上分组
2、在Class上分组
待补充
5、预期异常测试
预期异常测试通过在@Test注解后加入预期的Exception来进行添加,如下所示:
package com.course.testng; import org.testng.annotations.Test; public class ExpectedException { /** * 什么时候会用到异常测试?? * 在我们期望结果为某一个异常的时候 * 比如:我们传入了某些不合法的参数,程序抛出了异常 * 也就是说我的语气结果就是这个异常。 */ // 这是一个测试结果会失败的异常测试 @Test(expectedExceptions = RuntimeException.class) public void runTimeExceptionFailed(){ System.out.println("这是一个失败的异常测试"); } // 这是一个成功的异常测试 @Test(expectedExceptions = RuntimeException.class) public void runTimeExceptionSuccess(){ System.out.println("这是我的异常测试"); throw new RuntimeException(); } }
runTimeExceptionFailed运行结果:
这是一个失败的异常测试 org.testng.TestException: Method ExpectedException.runTimeExceptionFailed()[pri:0, instance:com.course.testng.ExpectedException@b065c63] should have thrown an exception of type class java.lang.RuntimeException at org.testng.internal.ExpectedExceptionsHolder.noException(ExpectedExceptionsHolder.java:89) at org.testng.internal.Invoker.handleInvocationResults(Invoker.java:1401) at org.testng.internal.Invoker.invokeMethod(Invoker.java:684) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112) at org.testng.TestRunner.privateRun(TestRunner.java:756) at org.testng.TestRunner.run(TestRunner.java:610) at org.testng.SuiteRunner.runTest(SuiteRunner.java:387) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382) 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:1293) at org.testng.TestNG.runSuitesLocally(TestNG.java:1218) at org.testng.TestNG.runSuites(TestNG.java:1133) at org.testng.TestNG.run(TestNG.java:1104) at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66) at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110) =============================================== Default Suite Total tests run: 1, Failures: 1, Skips: 0 =============================================== Process finished with exit code 0
runTimeExceptionSuccess运行结果如下:
这是我的异常测试 =============================================== Default Suite Total tests run: 1, Failures: 0, Skips: 0 =============================================== Process finished with exit code 0
6、超时测试
“超时”表示如果单元测试花费的时间超过指定的毫秒数,那TestNG将会中止它并将其标记为失败。此项常用于性能测试。如下为一个范例:
package com.course.testng; import org.testng.annotations.Test; public class TimeOutTest { @Test(timeOut = 3000)//单位为毫秒值 public void testSuccess() throws InterruptedException { Thread.sleep(2000); } @Test(timeOut = 2000) public void testFailed() throws InterruptedException { Thread.sleep(3000); } }
结果如下:
org.testng.internal.thread.ThreadTimeoutException: Method com.course.testng.TimeOutTest.testFailed() didn't finish within the time-out 2000 at org.testng.internal.InvokeMethodRunnable.runOne(InvokeMethodRunnable.java:69) at org.testng.internal.InvokeMethodRunnable.run(InvokeMethodRunnable.java:44) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) =============================================== Default Suite Total tests run: 2, Failures: 1, Skips: 0 =============================================== Process finished with exit code 0
7、分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 | 在本测试中的所有测试方法上使用的默认超时 |
8、依赖测试
有时,可能需要以特定顺序调用测试用例中的方法,或者希望在方法之间共享一些数据和状态。 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来实现依赖测试。 且这两个都支持正则表达式,如范例三所示,如下为几个使用范例:
- 范例一,被依赖方法pass:
package com.course.testng; import org.testng.annotations.Test; public class DependTest { @Test public void test1(){ System.out.println("test1 run"); } @Test(dependsOnMethods = {"test1"}) public void test2(){ System.out.println("test2 run"); } }
运行结果:
test1 run test2 run =============================================== Default Suite Total tests run: 2, Failures: 0, Skips: 0 =============================================== Process finished with exit code 0
- 被依赖方法执行失败:
package com.course.testng; import org.testng.annotations.Test; public class DependTest { @Test public void test1(){ System.out.println("test1 run"); throw new RuntimeException(); } @Test(dependsOnMethods = {"test1"}) public void test2(){ System.out.println("test2 run"); } }
运行结果如下:
test1 run java.lang.RuntimeException at com.course.testng.DependTest.test1(DependTest.java:10) 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:104) at org.testng.internal.Invoker.invokeMethod(Invoker.java:645) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112) at org.testng.TestRunner.privateRun(TestRunner.java:756) at org.testng.TestRunner.run(TestRunner.java:610) at org.testng.SuiteRunner.runTest(SuiteRunner.java:387) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382) 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:1293) at org.testng.TestNG.runSuitesLocally(TestNG.java:1218) at org.testng.TestNG.runSuites(TestNG.java:1133) at org.testng.TestNG.run(TestNG.java:1104) at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66) at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110) Test ignored. =============================================== Default Suite Total tests run: 2, Failures: 1, Skips: 1 =============================================== Process finished with exit code 0
- group依赖
9、参数化
TestNG中的最重要的功能是参数化测试。 在大多数情况下,会遇到业务逻辑需要大量测试的场景。 参数化测试允许开发人员使用不同的值一次又一次地运行相同的测试。
TestNG可以通过两种不同的方式将参数直接传递给测试方法:
- 使用testng.xml
- 使用dataprovider
1、使用textng.xml传送参数
代码如下:
package com.course.testng.paramter; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class ParamterTest { @Test @Parameters({"name","age"}) public void paramTest1(String name,int age){ System.out.println("name = " + name + "; age = " + age); } }
xml配置:
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="parameter">
<test name="param">
<classes>
<parameter name="name" value="zhangsan"/>
<parameter name="age" value="10"/>
<class name="com.course.testng.paramter.ParamterTest"/>
</classes>
</test>
</suite>
运行xml,结果如下:
name = zhangsan; age = 10 =============================================== parameter Total tests run: 1, Failures: 0, Skips: 0 =============================================== Process finished with exit code 0
2、使用@DataProvider
传递参数
@DataProvider
传递参数传参的类型必须要一致,带有@DataProvider
注解的函数返回值一定要是Object[][]。
代码如下:
package com.course.testng.paramter; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.lang.reflect.Method; public class DataProviderTest { @Test(dataProvider = "data") public void testDataProvider(String name,int age){ System.out.println("name =" + name +"; age=" + age); } @DataProvider(name="data") public Object[][] providerData(){ Object[][] o = new Object[][]{ {"zhangsan",10}, {"lisi",20}, {"wangwu",30} }; return o; } }
运行结果如下:
name =zhangsan; age=10 name =lisi; age=20 name =wangwu; age=30 =============================================== Default Suite Total tests run: 3, Failures: 0, Skips: 0 =============================================== Process finished with exit code 0