【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

浙公网安备 33010602011771号