参考博客https://blog.csdn.net/df0128/article/details/83243822;
TestNG支持用例或者组之间的依赖。
虽然我们有多种@Before
可以使用,看起来和依赖效果一样,但是被@Before
标记的部分不会作为用例执行结果展现,且其成功或者失败并不影响用例的运行,但是有时候我们又希望这些前置条件要通过才行,那么这时候依赖就派上用场了;
而有时候有些用例本来就是必须在另外一些用例之前运行并且必须成功才行,或者懒得写@Before
;
@Test
注解中使用属性dependsOnMethods
;@Test
注释中使用属性dependsOnGroups
;除此之外依赖还分为hard依赖和soft依赖:
methods
或者groups
必须全部pass
,否则被标识依赖的类或者方法将会被略过,在报告中标识为skip
,如后面的范例所示,此为默认的依赖方式;pass
也不会影响被标识依赖的类或者方法的运行,注意如果使用此方式,则依赖者和被依赖者之间必须不存在成功失败的因果关系,否则会导致用例失败。此方法在注解中需要加入alwaysRun=true
即可,如@Test(dependsOnMethods= {"TestNgLearn1"}, alwaysRun=true)
;还有一点需要知道的是这两种方式都支持正则表达式;
依赖支持注解依赖和testNG.xml标识依赖,下面将分别说明:
一下以一些范例来说明,注意依赖是可以依赖多个的,并非只能依赖一个:
代码:
public class DependTest1 {
@Test
public void dependTest1()
{
System.out.println("dependTest1");
}
@Test
public void dependTest2()
{
System.out.println("dependTest2");
}
@Test(dependsOnMethods= {"dependTest1","dependTest2"})
public void dependTest3()
{
System.out.println("dependTest3");
}
@Test(dependsOnMethods= "dependTest1")
public void dependTest4()
{
System.out.println("dependTest4");
}
}
运行结果;
dependTest1
dependTest2
dependTest3
dependTest4
PASSED: dependTest1
PASSED: dependTest2
PASSED: dependTest3
PASSED: dependTest4
===============================================
Default test
Tests run: 4, Failures: 0, Skips: 0
===============================================
代码:
public class DependTest1 {
@Test(groups= {"dependGroup1"})
public void dependTest1()
{
System.out.println("dependTest1");
}
@Test(groups= {"dependGroup1"})
public void dependTest2()
{
System.out.println("dependTest2");
}
@Test(dependsOnGroups= {"dependGroup1"})
public void dependTest3()
{
System.out.println("dependTest3");
}
}
结果:
dependTest1
dependTest2
dependTest3
PASSED: dependTest1
PASSED: dependTest2
PASSED: dependTest3
===============================================
Default test
Tests run: 3, Failures: 0, Skips: 0
===============================================
代码:
public class DependTest1 {
@Test(dependsOnMethods= "dependTest4", groups= {"dependGroup1"})
//@Test(groups= {"dependGroup1"})
public void dependTest1()
{
System.out.println("dependTest1");
}
@Test(groups= {"dependGroup1"})
public void dependTest2()
{
System.out.println("dependTest2");
}
@Test(dependsOnGroups= {"dependGroup1"})
public void dependTest3()
{
System.out.println("dependTest3");
}
@Test
public void dependTest4()
{
System.out.println("dependTest4");
}
}
结果;
dependTest2
dependTest4
dependTest1
dependTest3
PASSED: dependTest2
PASSED: dependTest4
PASSED: dependTest1
PASSED: dependTest3
===============================================
Default test
Tests run: 4, Failures: 0, Skips: 0
===============================================
代码:
public class DependTest1 {
@Test(dependsOnMethods= "dependTest4", groups= {"dependGroup1"})
public void dependTest1()
{
System.out.println("dependTest1");
}
@Test
public void dependTest4()
{
System.out.println("dependTest4");
Assert.assertFalse(true);
}
}
结果:
dependTest4
FAILED: dependTest4
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.DependTest1.dependTest4(DependTest1.java:32)
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: dependTest1
java.lang.Throwable: Method DependTest1.dependTest1()[pri:0, instance:com.demo.test.testng.DependTest1@31a5c39e] depends on not successfully finished methods
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1068)
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)
===============================================
Default test
Tests run: 2, Failures: 1, Skips: 1
===============================================
此处可以看到被依赖的dependTest4
失败后depentTest1
是会被skip
的
代码:
public class DependTest1 {
@Test(dependsOnMethods= "dependTest4", groups= {"dependGroup1"}, alwaysRun= true)
public void dependTest1()
{
System.out.println("dependTest1");
}
@Test()
public void dependTest4()
{
System.out.println("dependTest4");
Assert.assertFalse(true);
}
}
结果:
dependTest4
dependTest1
PASSED: dependTest1
FAILED: dependTest4
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.DependTest1.dependTest4(DependTest1.java:32)
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)
===============================================
Default test
Tests run: 2, Failures: 1, Skips: 0
===============================================
此处可以看到dependTest4
失败后并不影响dependTest1
的运行;
此部分是用于有@Factory注解的情况,代码如下:
public class FactoryTest {
private String host;
private int port;
public FactoryTest(String host, int port)
{
this.host=host;
this.port=port;
}
@Test
public void login()
{
System.out.println("login, host:"+host+";port"+port);
}
@Test(dependsOnMethods="login")
public void logout()
{
System.out.println("logout, host:"+host+";port"+port);
}
@Factory
public static Object[] create()
{
List<FactoryTest> list = new ArrayList<FactoryTest>();
list.add(new FactoryTest("10.10.10.1", 8080));
list.add(new FactoryTest("10.10.10.2", 8080));
return list.toArray();
}
}
xml:
运行结果:
login, host:10.10.10.2;port8080
logout, host:10.10.10.2;port8080
login, host:10.10.10.1;port8080
logout, host:10.10.10.1;port8080
===============================================
Suite
Total tests run: 4, Failures: 0, Skips: 0
===============================================
倘若group-by-instances
设置为false,则结果如下:
login, host:10.10.10.2;port8080
login, host:10.10.10.1;port8080
logout, host:10.10.10.2;port8080
logout, host:10.10.10.1;port8080
===============================================
Suite
Total tests run: 4, Failures: 0, Skips: 0
===============================================
如上这个例子是多环境的login和logout,如果不加group-by-instances="true"
的话就无法实现一个环境的完整login和logout了;
注意这里group-by-instances="true"
可以添加在
标签也可以在
标签,且不用的话默认为false
。
代码如下:
public class DependTest1 {
@Test(groups= {"dependGroup1"})
public void dependTest1()
{
System.out.println("dependTest1");
}
@Test(groups= {"dependGroup1"})
public void dependTest2()
{
System.out.println("dependTest2");
}
@Test(groups="dependGroup2")
public void dependTest4()
{
System.out.println("dependTest4");
Assert.assertFalse(false);
}
}
xml:
<suite name="Suite" parallel="none">
<test name="Test" group-by-instances="true">
<groups>
<dependencies>
<group name="dependGroup2" depends-on="dependGroup1" />
dependencies>
groups>
<classes>
<class name="com.demo.test.testng.DependTest1">
class>
classes>
test>
suite>
运行该xml结果为:
dependTest1
dependTest2
dependTest4
===============================================
Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
注意,如果依赖多个group
,则在xml中应当这样写depends-on="a b"
(其中a和b为两个group
的名称)。
@Test(groups = "init")
public class BaseTest {
public correctVM() {}
public serverStartedOk() {}
}
依赖方式如下:
@Test(dependsOnGroups = { "init.*" })
public class TestServer extends BaseTest {
public method1() { ... }
public method2() { ... }
...
}