Testng 的简单使用(二)-- 注解2
Testng 的简单使用(二)-- 注解2
4. 测试级别设置
创建测试用例时,大概分三个层级。
-
测试包(目录)
-
测试类(文件)
-
测试用例(
@Test
注解的方法)
4.1 指定运行测试包
首先看下项目的结构,我是将在主目录下的 testng.xml 文件移动到了 src/test 的目录下,如下图。
[外链图片转存失败(img-kSZ9LiSl-1566742864920)(pic/项目格式.png )]
此时的 testng.xml 文件位于 test 的文件夹下,内容配置如下所示
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="简单测试">
<packages>
<package name="sample"></package>
<package name="sample1"></package>
</packages>
</test>
</suite>
这样的设定后,右键 testng.xml 文件,然后点击 run
,执行效果如下图所示。
[外链图片转存失败(img-oepxpSjE-1566742864922)(pic/packages运行结果.png)]
会发现两个目录下所有的类都运行完成。具体的一些参数如下。
-
<packages>...</packages>
定义一组测试包。 -
<package.../>
定义一个测试包。- name 指定测试包(目录)的名称。
4.2 指定运行测试类
项目结构与上一小节 4.1 一致,testng.xml 文件内容配置如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="简单测试">
<classes>
<class name="sample.FirstTest"/>
<class name="sample1.ThirdTest"/>
</classes>
</test>
</suite>
右键 testng.xml 文件,然后点击 run
,执行结果如下图所示。
[外链图片转存失败(img-MXS92cie-1566742864925)(pic/classes运行结果.png)]
会发现在 testng.xml 配置文件中指定的两个文件夹下的两个类运行,未指定的类并没有运行。
4.3 指定运行测试用例
项目结构与 4.1 一致,testng.xml 的内容配置如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="简单测试">
<classes>
<class name="sample.FirstTest">
<methods>
<include name="FirstTest"/>
</methods>
</class>
<class name="sample1.ThirdTest">
<methods>
<include name="ThirdTest"/>
</methods>
</class>
</classes>
</test>
</suite>
右键 testng.xml 文件,然后点击 run
,执行结果如下图所示。
[外链图片转存失败(img-mJJUErvI-1566742864931)(pic/method运行结果.png)]
会发现指定类中的指定的测试用例执行,其他的并没有执行。具体的参数解析如下。
-
<methods>...</methods>
定义一组测试方法。 -
<include.../>
指定包含的测试用例(方法)。name
指定测试用例(方法)的名称。
注意: 测试方法 <methods>
必须包含在 <class>
标签中。
5. TestNG 用例分组
测试用例的划分
a. 根据用例的重要程度划分
- 重要程度: 低 ——> 中——>高
b. 根据用例的类型划分
- 类型: 正常——>异常
c. 实例
项目的结构还是用 4.1 的项目,如下图。
[外链图片转存失败(img-xyIQQt2A-1566742864935)(pic/项目格式.png )]
其中,此次模块只用了 sample/FirstTest 这个类,标签有 高、中、低、正常和异常 ,每个用例有两个标签 ,内容如下。
package sample1;
import org.testng.annotations.Test;
@Test(groups = {"功能测试"})
public class FirstTest {
@Test(groups = {"高", "正常"})
public void FirstTest(){
System.out.println("This is sample1 FirstTest");
}
@Test(groups = {"高", "正常"})
public void FirstTest2(){
System.out.println("This is sample1 FirstTest2");
}
@Test(groups = {"中", "正常"})
public void FirstTest3(){
System.out.println("This is sample1 FirstTest");
}
@Test(groups = {"低", "异常"})
public void FirstTest4(){
System.out.println("This is sample1 FirstTest2");
}
}
运行标签为 高 的用例, testng.xml 文件的配置如下。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="简单测试">
<groups>
<run>
<include name="高"/>
</run>
</groups>
<classes>
<class name="sample1.FirstTest"/>
</classes>
</test>
</suite>
右键 testng.xml 文件,然后点击 run
,这个配置将运行标签为 高 的用例,也就是前两个用例。具体一些参数的解析如下。
-
<groups>...</groups>
测试组标签。 -
<run>...</run>
运行测试。 -
<exclude>
根据 groups 的设置,排除不执行的用例。 -
<include>
根据 groups 的设置,指定执行的测试用例。
一开始,我们给 FirstTest 也划分了组 (groups = {"功能测试"}
),现在修改 testng.xml 的配置,完整的配置如下。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="简单测试">
<groups>
<run>
<exclude name="异常"/>
<include name="功能测试"/>
</run>
</groups>
<classes>
<class name="sample1.FirstTest"/>
</classes>
</test>
</suite>
执行这个配置,可以使 FirstTest 这个标记 功能测试
标签的类,除了 有 异常
标签的第四个用例外,都将执行。
6. TestNG 的执行顺序
一开始,我认为 TestNG 是按照顺序来执行的,结果发现并不是。然后发现要想按照顺序来执行,其实特别简单,有三种方法。
a. 按照排序
很好理解,就像字典的排序,通过字母的排序来进行的, TestNG 默认的运行方式就是按照排序来的。所以想要特定的顺序来执行的话,只需要在命名上按照顺序来就好了。
b. 按照优先级
在 @Test
的注解中,有一个参数是 priority
,也就是优先级,可以给每一个测试用例定义不同的优先级来决定运行的先后顺序。具体的用法如下所示。
package sample1;
import org.testng.annotations.Test;
@Test(groups = {"功能测试"})
public class FirstTest {
@Test(groups = {"高", "正常"}, priority = 4)
public void FirstTest(){
System.out.println("This is sample1 FirstTest");
}
@Test(groups = {"高", "正常"}, priority = 3)
public void FirstTest2(){
System.out.println("This is sample1 FirstTest2");
}
@Test(groups = {"中", "正常"}, priority = 2)
public void FirstTest3(){
System.out.println("This is sample1 FirstTest3");
}
@Test(groups = {"低", "异常"}, priority = 1)
public void FirstTest4(){
System.out.println("This is sample1 FirstTest4");
}
}
在这个类的文件名上直接右键,然后点击 Run
,不需要通过 testng,xml
文件来运行。运行的结果如下图所示。
[外链图片转存失败(img-loFwA9LR-1566742864939)(pic/priority设置运行结果.png)]
然后就会按照优先级的设置执行,其中数字越小,优先级越高。
c. 通过 testng.xml
文件修改配置
还是用到前边的例子,使用 FirstTest.java 这个类。具体的配置如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="简单测试">
<classes>
<class name="sample1.FirstTest">
<methods>
<include name="FirstTest4"/>
<include name="FirstTest2"/>
<include name="FirstTest3"/>
<include name="FirstTest"/>
</methods>
</class>
</classes>
</test>
</suite>
preserve-order
参数用于控制测试用例的执行顺序。如果为 true ,就会按照配置的顺序执行;如果为 false ,那么默认会按照用例的名称的有字母/数字的顺序执行。
注意: 不设置的情况下默认为true
d. 总结
三种方法中,执行的优先级顺序是 priority优先级 > testng.xml 配置文件 > 默认字母顺序 ,因此,设置优先级最好采用一种,以免有所冲突。
7. TestNG 用例依赖
a. 测试方法依赖
当一条用例执行失败时,其它用例必然也会失败,所以,我们就没有必要再运行其它用例了,这个时候我们就可以设置用例之间的依赖。
package sample1;
import org.testng.Assert;
import org.testng.annotations.Test;
public class SecondTest {
@Test
public void SecondTest(){
Assert.assertEquals(3 + 1 , 5);
}
@Test(dependsOnMethods = {"SecondTest"})
public void SecondTest2(){
Assert.assertEquals(3 + 2, 5);
}
}
dependsOnMethods
来设置用例的依赖,当 SecondTest() 运行失败时,则 SecondTest2() 则将不再被执行。
b. 测试组依赖
package sample1;
import org.testng.Assert;
import org.testng.annotations.Test;
public class SecondTest {
@Test(groups = {"test"})
public void SecondTest(){
Assert.assertEquals(3 + 1 , 5);
}
@Test(groups = {"test"})
public void SecondTest2(){
Assert.assertEquals(3 + 2, 5);
}
@Test(dependsOnGroups = {"test"})
public void SecondTest3(){
Assert.assertEquals(3 + 2, 5);
}
}
dependsOnGroups
来设置组的依赖,SecondTest() 和 SecondTest2() 同属于一个 test 组,SecondTest3() 依赖于 test 组,该组中有一条用例执行失败,则 SecondTest3() 不再执行。
8. TestNG 用例参数化
参数化也是测试用例中常用的技巧之一,它可以增加用例的可配置性和减少相同用例的编写。
8.1 通过 @Parameters
实现参数化
项目结构还是和之前的一样,这次使用的是 simple2/ThirdTest.java 这个类。具体的代码如下面所示。
package sample2;
import org.testng.Assert;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class ThirdTest {
@Test
@Parameters({"add1", "add2", "result"})
public void ThirdTest(int add1, int add2, int result){
Assert.assertEquals(add1 + add2, result);
System.out.println("add1 = " + add1 + "; " + "add2 = " + add2 + "; " + "result = " + result);
}
}
然后就是定义 testng.xml 文件,具体的配置如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true" name="简单测试">
<parameter name="add1" value="2"/>
<parameter name="add2" value="3"/>
<parameter name="result" value="5"/>
<classes>
<class name="sample2.ThirdTest"></class>
</classes>
</test>
</suite>
具体的参数解析如下。
-
<parameter.../>
定义测试数据-
name
定义数据的名字,在测试用例中通过该名字来获取对应的value
。 -
value
定义测试数据,通过对应的name
来获取该值。
-
运行 testng.xml
的结果如下图所示。
[外链图片转存失败(img-PIDySynp-1566742864942)(pic/parameter参数测试.png)]
会发现运行的结果参数就是我们在 testng.xml 中设置的值。
通过 @DataProvider
实现参数化
本次实例使用 simple2/ThirdTest.java 这个类,然后 @DataProvider
的使用方法如下面代码所示。
package sample2;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ThirdTest {
// 定义对象数组
@DataProvider(name = "add")
public Object[][] user(){
return new Object[][]{
{3, 2, 5},
{2, 2, 4},
{3, 3, 7}
};
}
@Test(dataProvider = "add")
public void ThirdTest(int add1, int add2, int result){
Assert.assertEquals(add1 + add2, result);
}
}
其中的某些参数解析如下:
@DataProvider
定义对象数组,数组名称为 add。
在 ThirdTest() 中通过 dataProvider="add"
来调用定义的对象数组,并通过参数获取相应的测试数据。
直接在 ThirdTest 类上右击,点击 Run
,运行此类,不需要在 testng.xml 文件中配置。执行结果如下图所示。
[外链图片转存失败(img-Are3UoS0-1566742864945)(pic/dataProvider参数测试.png)]
会发现,定义的数组中的所有的参数都被执行。
9. TestNG 多线程运行用例
TestNG 是唯一自身支持多程技术的单元测试框架。虽然代码级别的单元测试运行得很快,多线程的意义并不大。但如果是 UI 自动化测试的话运行速度就会非常慢,这个时候多线程技术就会变得很重要。
多线程的配置
接下来就是 testng.xml 文件的配置,请看下面。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" parallel="classes" thread-count="4">
<test name="简单测试">
<classes>
<class name="sample1.SecondTest"/>
<class name="sample2.ThirdTest"/>
</classes>
</test>
</suite>
-
parallel
设置多线程的级别划分。-
parallel="method"
TestNG 将在不同的线程中运行所有的测试方法。依赖方法也将在单独的线程中运行测试,但他们将尊重你指定的顺序。 -
parallel="tests"
TestNG 将在同一个线程中运行相同的标记的,但是每个标记将在一个单独的线程中。这将允许你将所有非线程安全的类分组在同一个中,并保证它们将在同一个线程中运行,同时利用尽可能多的县城来运行测试。 -
parallel="classes"
TestNG 将在同一个线程中同一个类中的所有方法,但是每个类都将在一个单独的线程中运行。 -
parallel="instances"
TestNG 将在同一个线程中运行相同实例中的所有方法,但是在两个不同实例上的两个方法将在不同的线程中运行。- thread-count 用于指定线程的个数。
-
10. TestNG 其他使用技巧
这里直接使用例子来演示,使用的类为 sample/FourthTest ,具体的代码如下。
package sample2;
import org.testng.annotations.Test;
public class FourthTest {
// 该条用例跳过执行
@Test(enabled = false)
public void FourthTest(){
System.out.println("This is FourthTest1");
}
// 设置用例超时时间
@Test(timeOut = 3000)
public void FourthTest2(){
System.out.println("This is FourthTest2");
}
// 设置用例抛出的异常类型
@Test(expectedExceptions = RuntimeException.class)
public void FourthTest3(){
Assert.assertEquals(2/0, 1);
}
}
一些参数的解析如下。
-
enabled
设置用例是否跳过执行,默认为 true,表示不跳过。false 表示跳过执行。 -
timeOut
设置用例运行的超时时间, 3000 单位为 毫秒 ,当用例运行时间超过 3000 毫秒则判定为失败。不管用例本身是否运行失败。 -
expectedExceptions
用来预设用例用例运行会出现的异常。例如 2/0 将会抛出 RuntimeException 类型的异常,如果出现异常则表示用例实行成功。
运行结果如下图所示。
11. TestNG 生成测试报告
11.1 通过 Maven 生成报告
切换到项目的根目录下,通过 mvn test
命令运行测试。如下图。
然后打开 target/surefire-reports/index.html ,将会看到整个项目的运行结果。
11.2 通过 Intellij IDEA 生成报告
在 Intellij IDEA 中默认运行测试用例是不会生成 HTML 报告的,需要进行简单的配置。首先打开配置的面板,具体步骤如下图。
然后就是进行具体的设置了,如下图。
然后点击 OK
按钮,完成设置。接下来用 Intellij IDEA 运行 TestNG 测试用例一样可以生成报告了。
如果感觉写的不错的话,请关注我的微信公众号:苦逼小码农