TestNG的参数化测试
2013-07-24 19:03
274 查看
软件测试往往需要测试大量的数据集,这样才能保证软件的稳定性和鲁棒性。JUnit没有提供方便传递测试参数的机制,所以,针对每个测试数据集,都需要单独写代码进行测试。这样浪费很多时间和精力重复写测试代码,它们只是参数不一样,测试逻辑完全一样。同时,测试代码和测试数据没有分离,为今后的维护埋下隐患。
TestNG在参数化测试方面,比JUnit有较大的优势。提供了两种传递参数的方式。testng.xml方式使代码和测试数据分离,方便扩展和维护。@DataProvider能够提供比较复杂的参数,同时方便产生具有一定规律的测试数据集。
<suite>和<test>标签定义了suite和test两种测试范围:一个test可以包含一系列的测试方法,一个suite可以包含多个独立的test。这两种测试范围有什么区别呢?一个test的所有测试方法都是针对同一测试对象,测试方法之间可以相互影响。而一个suite的每个test都是针对一个单独测试对象,两个test中的测试方法不会相互影响。
在这两种测试范围定义的参数,满足如下规律:
1)在Suite范围内定义某个参数的值,对所有的Test都有效。
2)在Test范围内定义某个参数的值,只是针对该Test有效。
3)如果同时在Suite和Test中定义某个参数,Test范围的值会屏蔽Suite的值。
示例代码如下:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite" verbose="1">
<parameter name="username" value="root" />
<parameter name="password" value="pwd" />
<parameter name="param" value="param" />
<test name="test1">
<parameter name="username" value="root2" />
<parameter name="password" value="pwd2" />
<classes>
<class name="HelloWorld" />
</classes>
</test>
<test name="test2">
<packages>
<package name="com.ibm.testng.test"></package>
</packages>
</test>
<suite>在suite中都定义了username和password两个参数,同时也在test1中也定义了这两个参数,但是在test2中没有定义。因此,test1中所有测试方法的username和password分别为“root2”和“pwd2”,而test2中所有测试方法的username和password分别为“root”和“pwd”。
在java代码中,给测试方法传递参数的示例代码如下:
@Parameters({"username"})
@Test(groups = "login")
public void inputUsername(String username) {
System.out.println("Input Username: " + username);
}
@Parameters({"password"})
@Test(groups = "login")
public void inputPassword(String password) {
System.out.println("Input Password: " + password);
}如果带参的函数被@Test标记为测试函数,但是没有被@Parameters标记,或者被@Parameters标记了,但是没有指定传递参数的名字,都会抛出一个TestNGException,这个函数就会被认为fail掉。
testng.xml只能传输简单类型的参数,不能传递Object类型。可以通过间接的方式,传递Object类型的参数。将所有参数化放到一个xml文件中,然后将该xml文件名作为参数,传递到一个XML解析器中。将xml解析的参数作为属性,创建所需的Object对象,然后对这些对象执行测试方法。
@DataProvider(name = "user")
public Object [][] createUser(Method m) {
System.out.println(m.getName());
return new Object[][] {
{"root", "root"},
{"test", "root"},
};
}
@Test(groups = "login", dependsOnGroups = "launch", dataProvider = "user")
public void verifyUser(String username, String password) {
System.out.println("Verify User : " + username + ":" + password);
assert username.equals(password);
}示例代码说明:
1)@DataProvider标记的createUser()提供名称为user的参数,同时输出接受参数的测试函数的名字。
2)@Test标记的测试函数verifyUser()接受名称为user的参数,同时判断参数username和password是否相等。
@DataProvider标记专门为测试方法提供参数的方法。这类方法必须返回Object[ ][ ]类型的二维数组,Object[]的每一行,都是测试方法的一个测试数据集,测试方法会为每个测试数据集执行一次。如果没有指定参数的名称,则默认为方法的名称,方法的名称没有限制。
@DataProvider标记的方法一般情况下没有参数,其实也可以带参数,但是这些参数的传递受到下面的两个限制:
1)@DataProvider标记的方法不可能是测试函数,因此不能通过@Parameters传递参数。
2)@DataProvider标记的方法只能被TestNG调用,因此用户不能通过调用的方式传递参数。
基于上面两个限制,@DataProvider标记的方法的参数化必须是特殊类型的,即TestNG在调用该方法时,可以通过反射机制获得。例如,例子中传递的参数是java.lang.reflect.Method类型,TestNG会将当前测试函数的名称传递给这个参数。当多个测试函数同时使用相同@DataProvider提供的参数时,需要根据测试方法提供不同的测试数据集时,这种特殊类型参数就显得非常有用。
TestNG在参数化测试方面,比JUnit有较大的优势。提供了两种传递参数的方式。testng.xml方式使代码和测试数据分离,方便扩展和维护。@DataProvider能够提供比较复杂的参数,同时方便产生具有一定规律的测试数据集。
1. testng.xml
可以通过<parameter>标签,在testng.xml中定义参数的值。对于同一参数,可以在不同地方定义不同值,因此需要注意testng.xml中的测试范围的问题。<suite>和<test>标签定义了suite和test两种测试范围:一个test可以包含一系列的测试方法,一个suite可以包含多个独立的test。这两种测试范围有什么区别呢?一个test的所有测试方法都是针对同一测试对象,测试方法之间可以相互影响。而一个suite的每个test都是针对一个单独测试对象,两个test中的测试方法不会相互影响。
在这两种测试范围定义的参数,满足如下规律:
1)在Suite范围内定义某个参数的值,对所有的Test都有效。
2)在Test范围内定义某个参数的值,只是针对该Test有效。
3)如果同时在Suite和Test中定义某个参数,Test范围的值会屏蔽Suite的值。
示例代码如下:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite" verbose="1">
<parameter name="username" value="root" />
<parameter name="password" value="pwd" />
<parameter name="param" value="param" />
<test name="test1">
<parameter name="username" value="root2" />
<parameter name="password" value="pwd2" />
<classes>
<class name="HelloWorld" />
</classes>
</test>
<test name="test2">
<packages>
<package name="com.ibm.testng.test"></package>
</packages>
</test>
<suite>在suite中都定义了username和password两个参数,同时也在test1中也定义了这两个参数,但是在test2中没有定义。因此,test1中所有测试方法的username和password分别为“root2”和“pwd2”,而test2中所有测试方法的username和password分别为“root”和“pwd”。
在java代码中,给测试方法传递参数的示例代码如下:
@Parameters({"username"})
@Test(groups = "login")
public void inputUsername(String username) {
System.out.println("Input Username: " + username);
}
@Parameters({"password"})
@Test(groups = "login")
public void inputPassword(String password) {
System.out.println("Input Password: " + password);
}如果带参的函数被@Test标记为测试函数,但是没有被@Parameters标记,或者被@Parameters标记了,但是没有指定传递参数的名字,都会抛出一个TestNGException,这个函数就会被认为fail掉。
testng.xml只能传输简单类型的参数,不能传递Object类型。可以通过间接的方式,传递Object类型的参数。将所有参数化放到一个xml文件中,然后将该xml文件名作为参数,传递到一个XML解析器中。将xml解析的参数作为属性,创建所需的Object对象,然后对这些对象执行测试方法。
2. @DataProvider
一个使用 @DataProvider传递参数的例子,代码如下:@DataProvider(name = "user")
public Object [][] createUser(Method m) {
System.out.println(m.getName());
return new Object[][] {
{"root", "root"},
{"test", "root"},
};
}
@Test(groups = "login", dependsOnGroups = "launch", dataProvider = "user")
public void verifyUser(String username, String password) {
System.out.println("Verify User : " + username + ":" + password);
assert username.equals(password);
}示例代码说明:
1)@DataProvider标记的createUser()提供名称为user的参数,同时输出接受参数的测试函数的名字。
2)@Test标记的测试函数verifyUser()接受名称为user的参数,同时判断参数username和password是否相等。
@DataProvider标记专门为测试方法提供参数的方法。这类方法必须返回Object[ ][ ]类型的二维数组,Object[]的每一行,都是测试方法的一个测试数据集,测试方法会为每个测试数据集执行一次。如果没有指定参数的名称,则默认为方法的名称,方法的名称没有限制。
@DataProvider标记的方法一般情况下没有参数,其实也可以带参数,但是这些参数的传递受到下面的两个限制:
1)@DataProvider标记的方法不可能是测试函数,因此不能通过@Parameters传递参数。
2)@DataProvider标记的方法只能被TestNG调用,因此用户不能通过调用的方式传递参数。
基于上面两个限制,@DataProvider标记的方法的参数化必须是特殊类型的,即TestNG在调用该方法时,可以通过反射机制获得。例如,例子中传递的参数是java.lang.reflect.Method类型,TestNG会将当前测试函数的名称传递给这个参数。当多个测试函数同时使用相同@DataProvider提供的参数时,需要根据测试方法提供不同的测试数据集时,这种特殊类型参数就显得非常有用。
相关文章推荐
- TestNG参数化测试Spring应用Dubbo接口
- TestNG参数化测试-数据提供程序 @DataProvider方式
- TestNG参数化测试-数据提供程序 @DataProvider方式
- TestNG入门教程(TestNG介绍、在Eclipse中安装TESTNG、测试小例子、基本注解、如何执行测试、按顺序执行Case、异常测试、组合测试、参数化测试、忽略测试、依赖测试、测试结果报告)
- TestNG的参数化测试、共享线程池配置、参数默认值配置
- TestNG 参数化测试
- TestNG 5 参数化测试
- TestNG 学习总结 - 参数化测试(十二)
- 【自动化测试与持续集成】基于Selenium2和TestNG的自动化测试的实现
- 使用testNG进行并发性能测试
- MonkeyTalk:脚本、变量、参数化脚本、数据驱动脚本、RunIf命令、自定义命令、测试和验证、Suites、命令执行
- JMeter 压力测试使用函数和 CSV 文件参数化 json 数据
- Junit--参数化测试
- easyMock, JMockIt和参数化测试笔记
- Selenium+Java+Appium+TestNg环境搭建——Web自动化测试与HTML5测试(2)
- 参数化的java性能测试,几组实验
- 安卓自动化测试工具MonkeyRunner之使用ID进行参数化,以及List选择某项和弹出框点击确定的写法
- Testng 测试框架源码阅读(一)
- testng生成报告ReportNG美化测试报告
- 持续集成:TestNG组织如何测试用例