TestNG is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use, such as:
TestNG is designed to cover all categories of tests: unit, functional, end-to-end, integration, etc...
功能 | Junit | TestNG |
---|---|---|
标注为类/方法为测试类和方法 | @Test | @Test |
标注为在suite中所有测试之前运行 | 无 | @BeforeSuite |
标注为在suite中所有测试之后运行 | 无 | @AfterSuite |
标注为在测试之前运行 | 无 | @BeforeTest |
标注为在测试之后运行 | 无 | @AfterTest |
标注为再试Group中第一个测试方法之前运行 | 无 | @BeforeGroups |
标注为再试Group中第一个测试方法之后运行 | 无 | @AfterGroups |
标注为当前测试类中第一个测试方法之前运行 | @BeforeClass | @BeforeClass |
标注为当前测试类中最后一个测试方法之后运行 | @AfterClass | @AfterClass |
标注为在每次测试方法之前运行 | @Before | @BeforeMethod |
标注为在每次测试方法之后运行 | @After | @AfterMethod |
忽略某测试,让其不执行 | @Ignore | @Test(enable=false) |
期待测试抛出什么异常 | @Test(excepted=XXXException.class) | @Test(exceptedExceptions=XXXException.class) |
测试超时,如果测试的执行时间超过了毫秒为单位设置的时间 | @Test(timeout=1000) | @Test(timeout=1000) |
由上述介绍总结几点TestNG和Junit主要的区别和适合测试工程师使用的原因:
注:以上对比指的是TestNG和Junit4版本的对比,最新的Junit5框架已经完善了功能特性,涵盖了TestNG所包含的功能,可以直接选用Junit5作为测试框架,只是Junit5还在推广普及中;具体可参考另外一篇博客: Junit5简介、构成、新特性及基本使用-常用注解、套件执行
maven依赖:
<dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.3</version> <scope>test</scope> </dependency> 复制代码
@Test
,另外在方法执行前后加上 @BeforeMethod
、 @AfterMethod
测试结果:
由测试结果可看到在每个测试用例执行前都会先执行@BeforeMethod注解的方法,之后都会执行@AfterMethod注解的方法 在测试类运行之前运行 @BeforeClass
和 @AfterClass
测试结果:
由测试结果可以看出在测试类执行前后会先后执行一次被@BeforeClass
和
@AfterClass
注解的方法
testNG.xml
,实际上文件的命名随意,you happy just ok! suite
-> test
-> classes
-> class
test
下的测试类看做是一个整体,其中的注解对整个 test
整体都是生效的 下面看实操演示,当前有3个测试类 SuiteTest1
、 SuiteTest2
和 SuiteTestConfig
resource
下创建套件配置文件
testNGSuite.xml
1)在 SuiteTest1
、 SuiteTest2
测试类中分别输入测试用例:
SuiteTestConfig
测试类中输入
@BeforeSuite
和
@AfterSuite
注解方法和
@Test
方法
3)最后在配置文件testNGSuite.xml
中配置套件执行顺序 将
SuiteTest1
、
SuiteTestConfig
"包"成一个
test
整体,
SuiteTest2
、
SuiteTestConfig
"包"成一个
test
整体;然后依顺序执行 ==注:suite和test Tag需要给一个name,否则会报错==
测试结果:
从测试结果我们可以看到@BeforeSuite
和
@AfterSuite
仅仅在suite执行前后分别执行一次
SuiteTestConfig
中输入 @BeforeTest
+ @AfterTest
注解的方法,xml套件配置不变
测试结果: @BeforeSuite,测试套件运行前执行 @BeforeTest,在test执行前执行 <------@BeforeTest 我是suiteTest1 我是SuiteTestConfig测试case @AfterTest,在test执行后执行 <------@AfterTest @BeforeTest,在test执行前执行 <------@BeforeTest 我是suiteTest2 我是SuiteTestConfig测试case @AfterTest,在test执行后执行 <------@AfterTest @AfterSuite,测试套件执行后执行 =============================================== testNG demo Total tests run: 4, Failures: 0, Skips: 0 =============================================== 复制代码由测试结果可以看到,在每个
test
执行前后都会先后执行一次由 @BeforeTest
、 @AfterTest
注解的方法 enable=false
测试结果:
由测试结果可以看到test1被忽略了,并没有执行 test1
和 test2
分为“ 测试1组”
和“ 测试2组
” 测试1组
执行前执行 @BeforeGroups
注解方法,在 测试2组
执行后执行 @AfterGroups
注解方法
测试结果:
ClassGroups1Test
、 ClassGroups2Test
、 ClassGroups3Test
1)分别将这3个测试类进行分组 Group1
、 Group2
、 Group3
2)将这3个测试类以3、2、1的执行顺序引入xml套件配置文件 <classes> <class name="groups.ClassGroups3Test"/> <class name="groups.ClassGroups2Test"/> <class name="groups.ClassGroups1Test"/> </classes> 复制代码3)设置场景,利用配置
<groups>
-> <run>
-> <include>/<exclude>
让 Group1
和 Group3
执行, Group2
不执行(实际上如果 <groups>
中直接不写 Group2
,它也不会执行) <groups> <run> <include name="Group1"/> <exclude name="Group2"/> <include name="Group3"/> </run> </groups> 复制代码xml套件配置文件呈现结果: 测试结果: 由测试结果可以看到,测试类分组在
Group3
和 Group1
的方法依次执行了,而 Group2
分组中的测试类未被执行 **注:**如果测试用例的逻辑顺序设计的较合理,平常使用分组的频率可能没那么高
@Test(exceptedExceptions = XXXException.class)
测试结果:
注:单元测试平常更多的可能由研发人员自己完成,一般功能和接口测试我们测试工程师期待的都是后端对异常处理后返回的一个状态码code和message信息
@Test(dependsOnMethods = {"funtion name"})
对另一个用例进行依赖
然后我们==直接运行pay方法==,结果如下:
由测试结果我们可以看到虽然我们直接执行了pay
方法,但是由于
pay
方法是依赖于
login
方法的,所以会先执行
login
方法
<parameter name="xx" value="xxx"/>
@Parameters
,并在xml配置文件中利用 <parameter name="xx" value="xxx"/>
的方式传参 注:也可用 <methods><methods/>
tag对指定的方法进行参数传递
xml里完成传参:
测试结果:
1)利用 @Test(dataProvider = "name")
+ @DataProvider(name="name")
将多组数据传递到一个方法中依次执行
测试结果:
2)利用@Test(dataProvider = "name")
+
@DataProvider(name="name")
指定测试方法,传递指定入参进行测试
分别单独运行方法userInfo1
和
userInfo2
得到测试结果: userInfo1:
userInfo2:
参数说明: 官方给出的解释是如下
简单来说就是:
invocationCount
表示方法要运行几次 threadPoolSize
表示线程池大小,且要配合 invocationCount
才起作用 现在将 userInfo1
方法用多线程执行10次,线程池大小设为4,打印当前线程id以观察验证
测试结果:
从测试结果中可以看到4个不同的线程一共将方法userInfo1
执行了10次
参数解释: 官方文档的解释如下:
parallel(methods|tests|classes)
:设置使用多线程,且有 methods|tests|classes
三种不同级别选择
methods
: 所有用例都可以在不同的线程下执行,包括依赖的用例 tests
: 同一个 <test>
中的用例运行在同一个线程下,不同 <test>
中的用例可以运行在不同线程下 classes
: 同一个 <class>
中的用例运行在同一个线程下,不同 <class>
中的用例可以运行在不同线程下 1)创建3个方法,打印线程ID
2) 2.1) methods-所有用例都可以在不同的线程下执行
parallel
为 methods
级别, thread-count
为3,进行测试
测试结果:
2.2) tests -同一个 <test>
中的用例运行在同一个线程下,不同 <test>
中的用例可以运行在不同线程下 再创建测试类 ThreadTest
,添加三个方法并打印thread ID
parallel
为 tests
级别, thread-count
为3,进行测试
测试结果:
2.3) classes -同一个 <class>
中的用例运行在同一个线程下,不同 <class>
中的用例可以运行在不同线程下 parallel
为 classes
级别, thread-count
为3,进行测试
测试结果:
注:虽然框架本身说明了是多线程安全的,但是由于我们自身编码可能不能保证严格规范,容易造成多线程不安全,所以建议不要适用多线程测试,而是适用多进程测试
参考链接: TestNG官方说明: testng.org/doc/index.h… IBM Developer: www.ibm.com/developerwo…