1 优点
1、比Junit涵盖功能更全面的测试框架 2、Junit更适合隔离性比较强的单元测试 3、TestNG更适合复杂的集成测试
2 maven中的使用
maven中引入
3 TestNG基本注解与执行顺序实战
3.1 Test、BeforeMethod、AfterMethod、BeforeClass、afterClass
package com.liuqi.testng;
import org.testng.annotations.*;
public class BasicAnnotation {
@Test
public void testCase1(){
System.out.println("这是测试用例1");
}
@Test
public void testCase2(){
System.out.println("Test这是测试用例2");
}
@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这是在类运行之后运行的");
}
}
运行结果:
beforeClass这是在类运行之前运行的
BeforeMethod这是在测试方法之前运行的
这是测试用例1
afterMethod这是在测试方法之后运行的
BeforeMethod这是在测试方法之前运行的
Test这是测试用例2
afterMethod这是在测试方法之后运行的
afterClass这是在类运行之后运行的
===============================================
Default Suite
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================
beforeclass、afterclass在类运行之前是否需要注册一些对象、赋值、静态方法赋值,然后其他method方法就可以使用 beforeMethod、afterMethod在每个测试用例运行之前和之后必须要运行的东西可以写在这里面
3.2 beforeSuit、afterSuit
package com.liuqi.testng;
import org.testng.annotations.*;
public class BasicAnnotation {
@Test
public void testCase1(){
System.out.println("这是测试用例1");
}
@Test
public void testCase2(){
System.out.println("Test这是测试用例2");
}
@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 beforeSuit(){
System.out.println("BeforeSuite类运行之前运行测试套件");
}
@AfterSuite
public void afterSuit(){
System.out.println("afterSuit类运行之后运行测试套件");
}
}
运行结果:
BeforeSuite测试套件
beforeClass这是在类运行之前运行的
BeforeMethod这是在测试方法之前运行的
这是测试用例1
afterMethod这是在测试方法之后运行的
BeforeMethod这是在测试方法之前运行的
Test这是测试用例2
afterMethod这是在测试方法之后运行的
afterClass这是在类运行之后运行的
afterSuit测试套件
===============================================
Default Suite
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================
3.3 测试套件
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="test">
<test name="login">
<classes>
<class name="com.liuqi.testng.suit.SuitConf"/>
<class name="com.liuqi.testng.suit.LoginTest"/>
</classes>
</test>
<test name="pay">
<classes>
<class name="com.liuqi.testng.suit.SuitConf"/>
<class name="com.liuqi.testng.suit.payTest"/>
</classes>
</test>
</suite>
3.4 忽略测试
package com.liuqi.testng;
import org.testng.annotations.Test;
public class ignoreTest {
@Test
public void ignore1(){
System.out.println("ignore1 执行!");
}
@Test(enabled = false)
public void ignore2(){
System.out.println("ignore2 执行");
}
@Test
public void ignore3(){
System.out.println("ignore3 执行");
}
}
结果:
ignore1 执行!
ignore3 执行
3.5 组测试
package com.liuqi.testng.groups;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
public class groupOnMethod {
@Test(groups = "server")
public void test1(){
System.out.println("这是服务端组的测试方法11");
}
@Test(groups = "server")
public void test2(){
System.out.println("这是服务端组的测试方法22");
}
@Test(groups = "client")
public void test3(){
System.out.println("这是客户端组的测试方法33");
}
@Test(groups = "client")
public void test4() {
System.out.println("这是客户端组的测试方法44");
}
@BeforeGroups("server")
public void beforeGroupsOnServer(){
System.out.println("这是服务端组运行之前运行的方法");
}
@AfterGroups("server")
public void afterGroupsOnServer(){
System.out.println("这是服务端组运行之后运行的方法");
}
@BeforeGroups("client")
public void beforeGroupsOnClient(){
System.out.println("这是客户端组运行之前运行的方法");
}
@AfterGroups("client")
public void afterGroupsOnClient(){
System.out.println("这是客户端组运行之后运行的方法");
}
}
运行结果:
这是服务端组的测试方法11
这是服务端组的测试方法22
这是客户端组的测试方法33
这是客户端组的测试方法44
运行结果与预期结果不符,@BeforeGroups和@AfterGroups的输出结果没有生效。
3.6 类分组测试
package com.liuqi.testng.groups;
import org.testng.annotations.Test;
@Test(groups = "stu")
public class GroupOnClass1 {
public void stu1(){
System.out.println("GroupOnClass1-----stu1运行");
}
public void stu2(){
System.out.println("GroupOnClass1-----stu2运行");
}
}
@Test(groups = "stu")
public class GroupOnClass2 {
public void stu1(){
System.out.println("GroupOnClass2-----stu1运行");
}
public void stu2(){
System.out.println("GroupOnClass2-----stu2运行");
}
}
@Test(groups = "teacher")
public class GroupOnClass3 {
public void teacher1(){
System.out.println("GroupOnClass3----teacher1运行");
}
public void teacher2(){
System.out.println("GroupOnClass3----teacher2运行");
}
}
xml配置
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="suitename">
<test name="runAll">
<classes>
<class name="com.liuqi.testng.groups.GroupOnClass1"/>
<class name="com.liuqi.testng.groups.GroupOnClass2"/>
<class name="com.liuqi.testng.groups.GroupOnClass3"/>
</classes>
</test>
<test name="onlyRunStu">
<groups>
<run>
<include name="stu"/>
</run>
</groups>
<classes>
<class name="com.liuqi.testng.groups.GroupOnClass1"/>
<class name="com.liuqi.testng.groups.GroupOnClass2"/>
<class name="com.liuqi.testng.groups.GroupOnClass3"/>
</classes>
</test>
</suite>
此时,xml配置后,运行该xml文件:
GroupOnClass1-----stu1运行
GroupOnClass1-----stu2运行
GroupOnClass2-----stu1运行
GroupOnClass2-----stu2运行
GroupOnClass3----teacher1运行
GroupOnClass3----teacher2运行
GroupOnClass1-----stu1运行
GroupOnClass1-----stu2运行
GroupOnClass2-----stu1运行
GroupOnClass2-----stu2运行
3.7 异常测试
package com.liuqi.testng.groups;
import org.testng.annotations.Test;
public class ExpectedError {
@Test(expectedExceptions = RuntimeException.class)
public void runTimeExcepetionFailed(){
System.out.println("这是一个失败的异常测试");
}
@Test(expectedExceptions = RuntimeException.class)
public void runTimeExcepetionSuccess(){
System.out.println("这是一个成功的异常测试");
throw new RuntimeException();
}
}
运行结果:
"D:\Program Files (x86)\software\jdk1.8\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\lib\idea_rt.jar=58762:D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\lib\idea_rt.jar;D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\plugins\testng\lib\testng-rt.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\charsets.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\deploy.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\access-bridge-32.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\cldrdata.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\dnsns.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\jaccess.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\jfxrt.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\localedata.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\nashorn.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunec.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunjce_provider.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunmscapi.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunpkcs11.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\zipfs.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\javaws.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jce.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jfr.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jfxswt.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jsse.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\management-agent.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\plugin.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\resources.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\rt.jar;D:\workspace\testNG\target\classes;C:\Users\liuqi49\.m2\repository\org\testng\testng\7.4.0\testng-7.4.0.jar;C:\Users\liuqi49\.m2\repository\com\beust\jcommander\1.78\jcommander-1.78.jar;C:\Users\liuqi49\.m2\repository\org\webjars\jquery\3.5.1\jquery-3.5.1.jar" com.intellij.rt.testng.RemoteTestNGStarter -usedefaultlisteners false -socket58761 @w@C:\Users\liuqi49\AppData\Local\Temp\idea_working_dirs_testng.tmp -temp C:\Users\liuqi49\AppData\Local\Temp\idea_testng.tmp
这是一个失败的异常测试
org.testng.TestException:
Method ExpectedError.runTimeExcepetionFailed()[pri:0, instance:com.liuqi.testng.groups.ExpectedError@1ceabc1] should have thrown an exception of type class java.lang.RuntimeException
at org.testng.internal.ExpectedExceptionsHolder.noException(ExpectedExceptionsHolder.java:82)
at org.testng.internal.TestInvoker.considerExceptions(TestInvoker.java:749)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:634)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at org.testng.TestRunner.privateRun(TestRunner.java:794)
at org.testng.TestRunner.run(TestRunner.java:596)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
at org.testng.SuiteRunner.run(SuiteRunner.java:276)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
at org.testng.TestNG.runSuites(TestNG.java:1063)
at org.testng.TestNG.run(TestNG.java:1031)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
这是一个成功的异常测试
===============================================
Default Suite
Total tests run: 2, Passes: 1, Failures: 1, Skips: 0
===============================================
Process finished with exit code 0
3.8 依赖测试
test2运行必须以test1为前提
package com.liuqi.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");
}
}
当运行test2()时,test1()也会跟着运行
test1 run
test2 run
当test1运行失败,test2将会被忽略
package com.liuqi.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");
}
}
运行结果:
"D:\Program Files (x86)\software\jdk1.8\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\lib\idea_rt.jar=52318:D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\lib\idea_rt.jar;D:\Program Files (x86)\software\IntelliJ IDEA Community Edition 2020.3\plugins\testng\lib\testng-rt.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\charsets.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\deploy.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\access-bridge-32.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\cldrdata.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\dnsns.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\jaccess.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\jfxrt.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\localedata.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\nashorn.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunec.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunjce_provider.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunmscapi.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\sunpkcs11.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\ext\zipfs.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\javaws.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jce.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jfr.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jfxswt.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\jsse.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\management-agent.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\plugin.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\resources.jar;D:\Program Files (x86)\software\jdk1.8\jre\lib\rt.jar;D:\workspace\testNG\target\classes;C:\Users\liuqi49\.m2\repository\org\testng\testng\7.4.0\testng-7.4.0.jar;C:\Users\liuqi49\.m2\repository\com\beust\jcommander\1.78\jcommander-1.78.jar;C:\Users\liuqi49\.m2\repository\org\webjars\jquery\3.5.1\jquery-3.5.1.jar" com.intellij.rt.testng.RemoteTestNGStarter -usedefaultlisteners false -socket52317 @w@C:\Users\liuqi49\AppData\Local\Temp\idea_working_dirs_testng.tmp -temp C:\Users\liuqi49\AppData\Local\Temp\idea_testng.tmp
test1 run
java.lang.RuntimeException
at com.liuqi.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:133)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at org.testng.TestRunner.privateRun(TestRunner.java:794)
at org.testng.TestRunner.run(TestRunner.java:596)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
at org.testng.SuiteRunner.run(SuiteRunner.java:276)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
at org.testng.TestNG.runSuites(TestNG.java:1063)
at org.testng.TestNG.run(TestNG.java:1031)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Test ignored.
===============================================
Default Suite
Total tests run: 2, Passes: 0, Failures: 1, Skips: 1
===============================================
Process finished with exit code 0
3.9 参数化测试
(1)通过xml传递参数
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="para">
<test name="param">
<classes>
<parameter name="name" value ="zhangsan"/>
<parameter name="age" value ="10"/>
<class name="com.liuqi.testng.para.paramterTest"/>
</classes>
</test>
</suite>
(2)通过dataProvider传数据
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",12},{"wangwu",20}
};
return o;
}
}
运行结果:
name=zhangsanage=10
name=lisiage=12
name=wangwuage=20
===============================================
Default Suite
Total tests run: 3, Passes: 3, Failures: 0, Skips: 0
===============================================
(3)方法传参
@Test(dataProvider = "methodData")
public void test1(String name, int age) {
System.out.println("test1方法 name=" + name + ";age=" + age);
}
@Test(dataProvider = "methodData")
public void test2(String name, int age) {
System.out.println("test2方法 name=" + name + ";age=" + age);
}
@DataProvider(name = "methodData")
public Object[][] methodDataTest(Method method) {
Object[][] result = null;
if (method.getName().equals("test1")) {
result = new Object[][]{
{"zhangsan",10},
{"lisi", 20}
};
} else if (method.getName().equals("test2")) {
result = new Object[][]{
{"wangwu",50},
{"zhaoliu", 60}
};
}
return result;
}
}
运行结果:
test1方法 name=zhangsan;age=10
test1方法 name=lisi;age=20
test2方法 name=wangwu;age=50
test2方法 name=zhaoliu;age=60
3.10 超时测试
~多久没响应超时
package com.liuqi.testng;
import org.testng.annotations.Test;
public class timeOutTest {
@Test(timeOut = 3000)
public void testSuccess() throws InterruptedException{
Thread.sleep(2000);
}
@Test(timeOut = 3000)
public void testFaild() throws InterruptedException{
Thread.sleep(4000);
}
}
运行结果
Default Suite
Total tests run: 2, Passes: 1, Failures: 1, Skips: 0
|