|
数据驱动特点
数据驱动是指在脚本固定的情况下,根据数据的条数来决定脚本的运行次数,即有几组数据,脚本就会
运行几遍。
数据驱动概述
数据驱动(Data Driven),这里强调的是数据,驱动即执行,那么数据驱动就是根据数据来执行测试脚本。
场景:测试登录,分别用刘能和赵四的帐号去测试。
先写一个公共方法来描述登录的过程:(伪代码实现)
- public boolean login(String username, String password){
- //do login
- }
- 再到测试方法里面去调用这个login方法/函数:
- public void test1(){
- login("liuneng","123456");
- }
- public void test2(){
- login("zhaosi","654321");
- }
复制代码
这样测试用例就写完了,执行test1与test2两个方法即可。但细心的你可能会发现test1与test2这两个测试方
法里的方法体除了数据,其它完全一样,这就存在重构的空间了:
- public boolean login(String[][] accounts){
- for(int i = 0; i<accounts.length; i++){
- //do login
- }
- }
- public void test(){
- String[][] accounts = [["liuneng","123456"],["zhaosi","654321"]];
- login(accounts);
- }
复制代码
经过重构后的代码,就有点数据驱动的意思了,根据accounts的length来决定login方法/函数体运行几次,这
样维护起来就方便了,假如又有一个老王的帐号想用来测试,就不需要再加一个测试方法了,只需要:
String[][] accounts = [["liuneng","123456"],["zhaosi","654321"],["laowang","000000"]];
重构后的代码,是不是令你很激动?原来这就是数据驱动!别急,淡定,这还不是真的数据驱动,因为上面
只有一个测试方法,最后执行完后,报告中记录的也是只有一个测试方法,而场景中:分别用刘能和赵四的
帐号去测试,是希望在测试报告中有两个测试方法出现,显然上面的代码还不能满足我们的需求,于是进一
步优化:
- public boolean login(String username, String password){
- //do login
- }
- public void test(String username, String password){
- login(username,password);
- }
- public void executor(){
- String[][] accounts = [["liuneng","123456"],["zhaosi","654321"]];
- for(int i = 0; i<accounts.length; i++){
- test(accounts[i][0],accounts[i][1]);
- }
- }
复制代码
是的,离数据驱动原理真相越来越近了,上面多了个executor方法,这是啥?这就是车子的发动机引擎啊,
就是测试脚本的执行引擎,让测试方法能够被执行起来,以及根据你所提供的测试数据的条数,决定测试
方法的执行次数,并且报告中会显示是两个测试方法,这就是数据驱动。测试框架就是一个执行引擎,并
且测试框架都会支持数据驱动这一基本诉求,比如TestNg里的dataProvider,junit里的Parameters等。下
面将为大家介绍TestNg里的dataProvider的用法。
TestNg数据驱动
TestNg的数据驱动也是以注解的形式来表达的:
- public class TestData {
- @DataProvider(name="dataDemo")
- public Object[][] dataProvider(){
- return new Object[][]{{1,2},{3,4}};
- }
- @Test(dataProvider="dataDemo")
- public void testDemo(int a, int b){
- int sum = a + b;
- System.out.println("this is sum: "+sum);
- }
- }
复制代码
说明:
TestNg的数据驱动的提供数据的方法用@DataProvider注解
@DataProvider中的name属性表示该数据源的名称
@DataProvider的方法要返回一个Object[][]的二维数组,当然也可以是Iterator的数据结构。
在测试方法中要用到数据源,则要在@Test中加上dataProvider属性,其值为数据源的名称。
Object[][]二维数组{{1,2},{3,4}}可以理解为有两组数据,分别为:{1,2},{3,4},所以测试方法会运行两
次,每一次运行时,测试方法的第一个参数a对应这一组数据中的第一个,也就是1或者3,第二个参数b则
对应这一组数据中的第二个,也就是2或者4,如果还有数据,则依次类推。当然数据源的每一组数据的个
数要大于或等于测试方法的参数个数,否则会报错,且数据类型要对应上,否则也会报错。
上面的示例中我们指定了@DataProvider数据源的名称为dataDemo,其实也可以不指定其名称,如果不指
定其名称,则数据源的名称为该数据源方法的方法名,比如:
- public class TestData {
- @DataProvider
- public Object[][] dataProvider(){
- return new Object[][]{{1,2},{3,4}};
- }
- @Test(dataProvider="dataProvider")
- public void testDemo(int a, int b){
- int sum = a + b;
- System.out.println("this is sum: "+sum);
- }
- }
复制代码
上面的例子中,@DataProvider数据源的方法与测试方法是在同一个测试类里,或者@DataProvider数据源的
方法放在测试类的父类中。但其实还有一种方式,@DataProvider数据源的方法可以单独的放在一个类里,比如:
- public class DataSource {
- @DataProvider
- public static Object[][] dataProvider(){
- return new Object[][]{{1,2},{3,4}};
- }
- }
- public class TestData {
- @Test(dataProvider="dataProvider",dataProviderClass=DataSource.class)
- public void testDemo(int a, int b){
- int sum = a + b;
- System.out.println("this is sum: "+sum);
- }
- }
复制代码
说明:
在测试方法中可以指定一个数据源的类,用dataProviderClass来指定
如果用了dataProviderClass指定数据源的类,则@DataProvider数据源的方法必须是static的。
其实@DataProvider数据源的方法,还可以提供一个参数Method,这个Method是指要使用该数据源的测试
方法的Method对象,比如:
- public class TestData {
- @DataProvider
- public Object[][] dataProvider(Method method){
- //method对象指使用该数据源的测试方法的Method对象,这是java中的一种反射
- System.out.println(method.getName());//输出testDemo
- return new Object[][]{{1,2},{3,4}};
- }
- @Test(dataProvider="dataProvider")
- public void testDemo(int a, int b){
- int sum = a + b;
- System.out.println("this is sum: "+sum);
- }
- }
- 很显然,有了这个Method对象后,就很方便我们扩展了,请看下面的例子:
- 先写一个类,将所有的数据都放在里面:
- public class DataSource {
- /**
- * dataMap里有两个数据源,分别是testDemo与testDemo1
- * 根据测试方法的名称,来使用不同的数据源。
- * 比如testDemo方法就用数据源{{1,2},{3,4}}
- * testDemo1方法就用数据源{{5,6},{3,4}}
- * @return
- */
- public Map<String, Object[][]> dataSource(){
- Map<String, Object[][]> dataMap = new HashMap<String, Object[][]>();
- Object[][] o1 = new Object[][]{{1,2},{3,4}};
- dataMap.put("testDemo", o1);
- Object[][] o2 = new Object[][]{{5,6},{7,8}};
- dataMap.put("testDemo1", o2);
- return dataMap;
- }
- }
- 再结合到@DataProvider数据源方法与测试方法中去:
- public class TestData {
- @DataProvider
- public Object[][] dataProvider(Method method){
- DataSource data = new DataSource();
- Object[][] obj = data.dataSource().get(method.getName());
- return obj;
- }
- @Test(dataProvider="dataProvider")
- public void testDemo(int a, int b){
- int sum = a + b;
- System.out.println("this is sum: "+sum);
- }
- @Test(dataProvider="dataProvider")
- public void testDemo1(int a, int b){
- int sum = a + b;
- System.out.println("this is sum: "+sum);
- }
- }
- 以上两个测试方法用到了同一个数据源@DataProvider,这样为我们以后写测试框架定下了基调。
- enum的使用
- enum是java中的一个关键字,中文翻译过来是枚举,先来看看用法:
- public enum TestEnum {
- /**
- * 定义两组数据,分别是{200,"success."}与{400,"failed."}
- * 枚举的意思是根据定义好的数据,来生成对象,有几组数据,就生成几个对象
- */
- SUCCESS(200,"success."),
- FAIL(400,"failed.");
- private int retCode;
- private String retMsg;
- private TestEnum(int retCode, String retMsg) {
- this.retCode = retCode;
- this.retMsg = retMsg;
- }
- public int getRetCode() {
- return retCode;
- }
- public String getRetMsg() {
- return retMsg;
- }
- public static void main(String[] args) {
- System.out.println(TestEnum.SUCCESS.getRetCode());//输出200
- System.out.println(TestEnum.FAIL.getRetMsg());//输出failed.
- }
- }
复制代码
|
|