【Java自动化测试】-TestNG操作详解
一、 TestNG使用流程
1.1TestNG安装
本文以IDEA+Maven为例介绍TestNG,IntelliJ IDEA版本为IntelliJ IDEA。
IntelliJ IDEA中默认集成了TestNG,点击File->Settings,如下图:
1.2 创建Maven项目
点击File->new-Project,如图
创建基于Maven的项目
创建名字为MavenTest的项目,创建完成后如下图
1.3 Maven配置
在工程的pom.xml中需要添加如下依赖:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>MavenTest</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.10</version> </dependency> </dependencies> </project>
1.4 项目TestNG测试类
点击类名Test,按alt+entet键,创建单元测试类
点击Create Test
OK,生成测试类
1.5 运行TestNG
运行结果:
二、TestNG常用注解
TestNG常用注解:
注解 | 描述 |
@BeforeSuite | 被注释的方法将在所有测试运行前运行(相当于前置条件) |
@AfterSuite |
被注释的方法将在所有测试运行后运行比如关闭浏览器(使执行其他用例时处于初始状态) |
@BeforeTest | 被注释的方法将在测试运行前运行 |
@AfterTest | 被注释的方法将在测试运行后运行 |
@BeforeGroups |
被配置的方法将在列表中的gourp前运行。这个方法保证在第一个属于这些组的测试方法调用 前立即执行 |
@AfterGroups |
被配置的方法将在列表中的gourp后运行。这个方法保证在最后一个属于这些组的测试方法调 用后立即执行 |
@BeforeClass | 被注释的方法将在当前类的第一个测试方法调用前运行 |
@AfterClass | 被注释的方法将在当前类的所有测试方法调用后运行 |
@BeforeMethod | 被注释的方法将在每一个测试方法调用前运行 |
@AfterMethod | 被注释的方法将在每一个测试方法调用后运行 |
@DataProvider |
标记一个方法用于为测试方法提供数据。 被注释的方法必须返回Object[][],其中每个Object[] 可以指派为这个测试方法的参数列表。从这个DataProvider接收数@Test方法需要使用一个和 当前注释相同名称的dataProvider名称 |
@Factory |
标记方法作为一个返回对象的工厂, 这些对象将被TestNG用于作为测试类。这个方法必须返回 Object[] |
@Listeners | 定义一个测试类的监听器 |
@Parameters | 描述如何传递参数给@Test方法 |
@Test | 标记一个类或方法作为测试的一部分 |
备注:
Before开头的注解一般用于初始化环境、 准备测试环境 after开头的注解一般用于执行测试的环境清理工作 DataProvider一般用作参数化用的, 属于数据驱动自动化(即不同的测试数据测试相同的测试逻辑) Listeners 自定义日志或者监控一些testNG用例执行成功或者失败的时候做些特别的事情 Parameters可以把xml文件定义的参数传递到测试程序或者测试类中来使用
案例:
public class yihuqingjiu_test_demo { @Test public void testCase1() { System.out.println("in test case 1"); } @Test public void testCase2() { System.out.println("in test case 2"); } @BeforeMethod public void beforeMethod() { System.out.println("in beforeMethod"); } @AfterMethod public void afterMethod() { System.out.println("in afterMethod"); } @BeforeClass public void beforeClass() { System.out.println("in beforeClass"); } @AfterClass public void afterClass() { System.out.println("in afterClass"); } @BeforeTest public void beforeTest() { System.out.println("in beforeTest"); } @AfterTest public void afterTest() { System.out.println("in afterTest"); } @BeforeSuite public void beforeSuite() { System.out.println("in beforeSuite"); } @AfterSuite public void afterSuite() { System.out.println("in afterSuite"); } }
运行结果:
in beforeSuite
in beforeTest
in beforeClass
in beforeMethod
in test case 1
in afterMethod
in beforeMethod
in test case 2
in afterMethod
in afterClass
in afterTest
TestNG的执行过程如下: 首先beforeSuite()方法执行一次。 最后afterSuite的()方法执行一次。 其次方法 beforeTest(), beforeClass(), afterClass() 和afterTest() 方法各执行一次。 beforeMethod()方法在执行每个测试用例之前执行一次。 afterMethod()方法在执行每个测试用例之后执行一次。
三、TestNG常用断言
assertEqual ([String message], expected value, actual value) 断言两个值相等。值可能是类型有 int, short, long, byte, char or java.lang.Object. 第一个参数是一个可选的字符串消息; assertTrue([String message], boolean condition) 断言一个条件为真; assertFalse([String message],boolean condition) 断言一个条件为假; assertNotNull([String message], java.lang.Object object) 断言一个对象不为空(null); assertNull([String message], java.lang.Object object) 断言一个对象为空(null); assertSame([String message], java.lang.Object expected, java.lang.Object actual) 断言两个对象引用相同的对象; assertNotSame([String message], java.lang.Object unexpected, java.lang.Object actual) 断言两个对象不是引用同一个对象; assertArrayEquals([String message], expectedArray, resultArray) 断言预期数组和结果数组相等。数组的类型可能是 int, long, short, char, byte or java.lang.Object.;
四、使用maven运行
需要在pom文件中,指明testng.xml文件的位置。
maven使用surefire这个插件进行测试,可以执行testng或者Junit脚本。
语法为 <suiteXmlFile>src/test/resources/testNGFilesFolder/${testNgFileName}.xml</suiteXmlFile>
<dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.8</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19</version> <configuration> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile>//该文件位于工程根目录时,直接填写名字,其它位置要加上路径。 </suiteXmlFiles> </configuration> </plugin> </plugins> </build>
五、TestNG忽略测试
通过注解@Test(enabled = false)
来将其忽略掉,此用例就不会运行了,如下范例:
import org.testng.annotations.Test; public class TestCase1 { @Test(enabled=false) public void TestNgLearn1() { System.out.println("this is TestNG test case1"); } @Test public void TestNgLearn2() { System.out.println("this is TestNG test case2"); } }
运行结果:
this is TestNG test case2 PASSED: TestNgLearn2
六、TestNG超时测试
超时”表示如果单元测试花费的时间超过指定的毫秒数,那么TestNG将会中止它并将其标记为失败。如下为一个范例:
import org.testng.annotations.Test; public class TestCase1 { @Test(timeOut = 5000) // time in mulliseconds public void testThisShouldPass() throws InterruptedException { Thread.sleep(4000); } @Test(timeOut = 1000) public void testThisShouldFail() { while (true){ // do nothing } } }
结果如下:
PASSED: testThisShouldPass FAILED: testThisShouldFail org.testng.internal.thread.ThreadTimeoutException: Method com.demo.test.testng.TestCase1.testThisShouldFail() didn't finish within the time-out 1000 at com.demo.test.testng.TestCase1.testThisShouldFail(TestCase1.java:37) 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.InvokeMethodRunnable.runOne(InvokeMethodRunnable.java:54) 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)
七、分组测试
顾名思义,是将不同的用例分组,然后再testng.xml文件中配置信息,而执行相应组的用例,代码实现如下,仅供参考:
package com.ui.day4; import org.testng.Assert; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; public class yihuqingjiu_test_group { ca a; @BeforeSuite(groups = {"冒烟","回归"}) public void reday() { a = new ca(); } @Test(groups = "冒烟") public void add() { Assert.assertEquals(a.add(5, 6), 11); } @Test(groups = "冒烟") public void min() { Assert.assertEquals(a.minus(6, 5), 1); } @Test(groups = "冒烟") public void cheng() { Assert.assertEquals(a.cheng(6, 5), 30); } @Test(groups = "回归") public void cheng1() { Assert.assertEquals(a.cheng(6, 5), 30); } @Test(groups = "回归") public void chu() { Assert.assertEquals(a.chu(5, 5), 1); } }
testng.xml文件配置如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Suite1" verbose="3"> <test name="test_one"> <groups> <run> <include name="回归" /> </run> </groups> <classes> <class name="com.ui.day4.test_group"></class> </classes> </test> </suite>
八、suite套件测试
测试套件是用于测试软件程序的行为或一组行为的测试用例的集合。 在TestNG中,我们无法在测试源代码中定义一个套件,但它可以由一个XML文件表示,因为套件是执行的功能。 它还允许灵活配置要运行的测试。 套件可以包含一个或多个测试,并由<suite>标记定义。<suite>是testng.xml的根标记。 它描述了一个测试套件,它又由几个<test>部分组成。
下表列出了<suite>接受的所有定义的合法属性。
suite常用属性介绍 | |
注解 | 描述 |
@name | suite的名称, 必须参数 |
@verbose | 命令行信息打印等级, 不会影响测试报告输出内容; 可选值(1|2|3|4|5) |
@parallel |
是否多线程并发运行测试; 可选值(false | methods | tests | classes |instances)默认 "false" |
@thread-count | 当为并发执行时的线程池数量, 默认为"5" |
@annotations | 获取注解的位置, 如果为"javadoc", 则使用javadoc注解, 否则使用jdk注解 |
junit | 是否以Junit模式运行, 可选值(true | false), 默认"false" |
@time-out | 为具体执行单元设定一个超时时间, 具体参照parallel的执行单元设置; 单位为毫秒 |
九、自定义执行顺序测试
按照一定的顺序去执行测试方法, 通过priority属性去设 置,如下代码实现:
public class yihuqingjiu_demo { @Test(priority=2) public void print3(){ System.out.println("壶"); } @Test(priority=0) public void print1(){ System.out.println("温"); } @Test(priority=1) public void print2(){ System.out.println("一"); } @Test(priority=4) public void print5(){ System.out.println("酒"); } @Test(priority=3) public void print4(){ System.out.println("清"); } }
执行顺序为print1--->print2--->print3--->print4--->print5
属性值为0代表最高优先级
还可以在testng.xml文件中设置,设置如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Suite1"> <test name="test" preserve-order="true"> <classes> <class name="com.ui.day4.test_demo"> <methods> <include name="print5" /> <include name="print2" /> <include name="print4" /> <include name="print1" /> <include name="print3" /> </methods> </class> </classes> </test> </suite>
preserve-order属性设置为true
依据include配置的顺序执行测试方法
十、依赖测试
有时,我们可能需要以特定顺序调用测试用例中的方法,或者可能希望在方法之间共享一些数据和状态。 TestNG支持这种依赖关系,因为它支持在测试方法之间显式依赖的声明。
TestNG允许指定依赖关系:
在@Test注释中使用属性dependsOnMethods
在@Test注释中使用属性dependsOnGroups
在TestNG中,我们使用dependOnMethods和dependsOnGroups来实现依赖测试。 且这两个都支持正则表达式,如范例三所示,如下为几个使用范例:
案例1:被依赖方法pass:
public class TestCase1 { @Test(enabled=true) public void TestNgLearn1() { System.out.println("this is TestNG test case1"); } @Test(dependsOnMethods= {"TestNgLearn1"}) public void TestNgLearn2() { System.out.println("this is TestNG test case2"); } }
运行结果:
this is TestNG test case1 this is TestNG test case2 PASSED: TestNgLearn1 PASSED: TestNgLearn2
案例2: 被依赖方法fail:
public class TestCase1 { @Test(enabled=true) public void TestNgLearn1() { System.out.println("this is TestNG test case1"); Assert.assertFalse(true); } @Test(dependsOnMethods= {"TestNgLearn1"}) public void TestNgLearn2() { System.out.println("this is TestNG test case2"); } }
运行结果:
this is TestNG test case1 FAILED: TestNgLearn1 junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:47) at junit.framework.Assert.assertTrue(Assert.java:20) at junit.framework.Assert.assertFalse(Assert.java:34) at junit.framework.Assert.assertFalse(Assert.java:41) at com.demo.test.testng.TestCase1.TestNgLearn1(TestCase1.java:26) 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 org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) SKIPPED: TestNgLearn2
十一、参数化测试
TestNG可以通过两种不同的方式将参数直接传递给测试方法:
下面分别介绍两种传参方式
1、使用textng.xml传送参数
范例代码如下:
public class TestCase1 { @Test(enabled=true) @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); } @Test(dependsOnMethods= {"TestNgLearn1"}) public void TestNgLearn2() { System.out.println("this is TestNG test case2"); } }
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> <!-- Test --> </suite> <!-- Suite -->
运行xml,结果如下:
this is TestNG test case1, and param1 is:1011111; param2 is:10 this is TestNG test case2 =============================================== Suite Total tests run: 2, Failures: 0, Skips: 0 ===============================================
2、使用@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); } @Test(dependsOnMethods= {"TestNgLearn1"}) public void TestNgLearn2() { System.out.println("this is TestNG test case2"); } }
运行此class,结果为:
this is TestNG test case1, and param1 is:10; param2 is:20 this is TestNG test case1, and param1 is:100; param2 is:110 this is TestNG test case1, and param1 is:200; param2 is:210 this is TestNG test case2 PASSED: TestNgLearn1(10, 20) PASSED: TestNgLearn1(100, 110) PASSED: TestNgLearn1(200, 210) PASSED: TestNgLearn2
本文来自博客园,作者:橘子偏爱橙子,转载请注明原文链接:https://www.cnblogs.com/xfbk/p/16996360.html