[☕【Java技术指南】「TestNG专题」单元测试框架之TestNG使用教程指南(上)],继续开展我们的下篇的TestNG的技术特性。
分组测试即为使用group,如果你使用xml的话就是里边的标签,如果是直接在class中,是通过@Test(groups=“group2”)这种方式来分组,如第四节的注解说明中的那个例子,分了两个group,而且@BeforeGroup是需要添加group名称才可以正确挂载到该group下的。
这个group说明可以是在单个的测试方法上,也可以在class上,只要具有同样的group名称都会在同一个group中,同时group名称可以有多个,类似@Test(groups = {“mysql”,“database”})这种,范例如下:
一个测试文件NewTest.class:
public class NewTest {
@Test(groups="group1")
public void test1() {
System.out.println("test1 from group1");
Assert.assertTrue(true);
}
@Test(groups="group1")
public void test11() {
System.out.println("test11 from group1");
Assert.assertTrue(true);
}
@Test(groups="group2")
public void test2()
{
System.out.println("test2 from group2");
Assert.assertTrue(true);
}
@BeforeTest
public void beforeTest()
{
System.out.println("beforeTest");
}
@AfterTest
public void afterTest()
{
System.out.println("afterTest");
}
@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");
}
@BeforeGroups(groups="group1")
public void beforeGroups()
{
System.out.println("beforeGroups");
}
@AfterGroups(groups="group1")
public void afterGroups()
{
System.out.println("afterGroups");
}
@BeforeMethod
public void beforeMethod()
{
System.out.println("beforeMethod");
}
@AfterMethod
public void afterMethod()
{
System.out.println("afterMethod");
}
}
@Test(groups= "group2")
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");
}
}
beforeSuite
beforeTest
beforeClass
beforeGroups
beforeMethod
test1 from group1
afterMethod
beforeMethod
test11 from group1
afterMethod
afterGroups
beforeMethod
test2 from group2
afterMethod
afterClass
this is TestNG test case2
afterTest
afterSuite
如上所示,先运行了group1的两个用例,再运行group2的两条用例;
注意在xml标识group,需要将要运行的group加进来,同时还要将被标识这些group的class也加进来,不被加进去的不会运行;
测试套件是用于测试软件程序的行为或一组行为的测试用例的集合。 在TestNG中,我们无法在测试源代码中定义一个套件,但它可以由一个XML文件表示,因为套件是执行的功能。 它还允许灵活配置要运行的测试。
套件可以包含一个或多个测试,并由标记定义。是testng.xml的根标记。 它描述了一个测试套件,它又由几个部分组成。在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
下表列出了接受的所有定义的合法属性。
可能需要以特定顺序调用测试用例中的方法,或者可能希望在方法之间共享一些数据和状态。 TestNG支持这种依赖关系,因为它支持在测试方法之间显式依赖的声明。
除此之外依赖还分为hard依赖和soft依赖:
在TestNG中,我们使用dependOnMethods和dependsOnGroups来实现依赖测试。 且这两个都支持正则表达式,如范例三所示,如下为几个使用范例:
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
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
如下所示,method1依赖group名称为init的所有方法:
@Test(groups = { "init" })
public void serverStartedOk() {}
@Test(groups = { "init" })
public void initEnvironment() {}
@Test(dependsOnGroups = { "init.*" })
public void method1() {}
这里init这个group中的两个方法的执行顺序如果没有在xml中指明则每次运行的顺序不能保证
TestNG中的另一个有趣的功能是参数化测试。 在大多数情况下,您会遇到业务逻辑需要大量测试的场景。 参数化测试允许开发人员使用不同的值一次又一次地运行相同的测试。
TestNG可以通过两种不同的方式将参数直接传递给测试方法:
下面分别介绍两种传参方式:
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");
}
}
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
===============================================
此处需要注意,传参的类型必须要一致,且带有@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");
}
}
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
前面讲的大多都是以测试脚本为基础来运行的,少部分是以xml运行,这里以xml来讲解下:
testNG.xml文件的最外层标签即suite,即测试套件,其下可以有多个和,其有几个可以添加的属性在第十节的分suite测试中有做说明,这里做下详细说明:
此属性属于必须要有的,值可以自行设定,此名字会在testNG的报告中看到;
此属性为指定testNG报告的详细程度,从0开始到10,其中10为最详细,默认生成的xml此属性值为1;
此属性是指代运行方式,默认为none,即串行运行方式;并行执行方法包括如下几种,下面做分别说明:
此属性用于指定线程数,按照需要输入,需要parallel参数非none时才可以添加;
此项为注解的级别,为methods级别和class级别,一般不用设置;
此属性用于指定超时时间,该suite下所有的用例的超时时间;
此项用于那些有依赖的方法,且被依赖的对象有多个重载对象,因为如果是依赖方法,且该方法有多个重载方法,则默认是会将所有重载方法都跑完再运行被依赖方法,但有时候我们不想这样,则将此项设置为true即可;
值可输入true或者false,如果为true,则用例执行会按照在xml中的顺序执行,否则会乱序执行,不添加此属性的话默认是按顺序执行的;
2、test标签
此标签无特别意义,其下可以包括多个标签,如groups、classes等,如下介绍下几种书写方式:
选择一个包中的全部测试脚本(包含子包)
选择一个包中的某些组
高级应用:
其他的话就是测试脚本的选择了,有三种方式:
选择一个包
选择一个类
选择一个方法
这里也支持正则表达式,例如: