Spring集成TestNG参数化批量测试

介绍

在TestNG中,一个强大的功能是参数测试。在大多数情况下,你会遇到这样一个场景,业务逻辑需要一个巨大的不同数量的测试。参数测试,允许开发人员运行同样的测试,一遍又一遍使用不同的值。

TestNG让你直接传递参数测试方法两种不同的方式:

  • testng.xml配置参数:在testng.xml文件中定义的简单参数,然后在源文件中引用这些参数

  • DataProvider注解: 当你需要通过复杂的参数或参数需要创建从Java(复杂的对象,对象读取属性文件或数据库等..),在这种情况下,可以将参数传递使用数据提供者。数据提供者@DataProvider的批注的方法。这个注解只有一个字符串属性:它的名字。如果不提供名称,数据提供者的名称会自动默认方法的名称。数据提供者返回一个对象数组。

而本文介绍在Spring中集成TestNG测试框架,是以CSV外部输入参数为参数,通过DataProvider注解生成TestNG测试所需外部参数:

  • 相关源码已经在集成在我的github项目AdminEAP中。

说明

  • 文件结构

    这里写图片描述

  • 运行结果

这里写图片描述

代码示例

在BaseTest类中,含有DataProvider注解的方法,该数据提供者方法,按照测试类名和测试方法名找到外部csv的文件,并把文件中的数据参数化,提供给集成了BaseTest的类

  • Maven中引入外部依赖
    <!--spring-test-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.0.8.RELEASE</version>
    </dependency>
    <!--csv reader-->
    <dependency>
        <groupId>net.sf.supercsv</groupId>
        <artifactId>super-csv</artifactId>
        <version>2.4.0</version>
    </dependency>
    <!--testng-->
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.9.10</version>
    </dependency>
  • 数据提供者父类 BaseTest.java
package com.billJiang.framework.testng;


import com.billJiang.framework.base.pojo.CsvPOJO;
import com.billJiang.framework.base.pojo.CsvRow;
import com.billJiang.framework.utils.CsvUtil;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.billJiang.framework.utils.DateUtil;

/**
 * Created by billJiang on 2016/10/22.
 */
@ContextConfiguration(locations = { "classpath:spring-hibernate.xml","classpath:spring.xml" })
@TransactionConfiguration(defaultRollback = true)
public class BaseTest extends AbstractTestNGSpringContextTests {

    @DataProvider
    public Object[][] dataProvider(ITestContext context, Method method) {
        CsvPOJO csvPojo = CsvUtil.getCaseList(this.getClass().getSimpleName() + "_" + method.getName() + ".csv");
        Class<?>[] types = method.getParameterTypes();
        int param_len = types.length;

        int size = csvPojo.getRows().size();
        Object[][] result = new Object[size][];
        for (int i = 0; i < csvPojo.getRows().size(); i++) {
            CsvRow row = csvPojo.getRows().get(i);
            List<String> objList = row.getCols();
            int obj_len = objList.size();
            if (param_len != obj_len) {
                throw new RuntimeException("CSV参数个数与测试方法" + method.getName() + "参数个数不一致");
            }
            // 类型转换
            List<Object> obj_list = new ArrayList<Object>();
            for (int j = 0; j < obj_len; j++) {
                if (types[j] == String.class) {
                    obj_list.add(objList.get(j));
                } else if (types[j] == Integer.class) {
                    obj_list.add(Integer.valueOf(objList.get(j)));
                } else if (types[j] == Double.class) {
                    obj_list.add(Double.valueOf(objList.get(j)));
                } else if (types[j] == Float.class) {
                    obj_list.add(Float.valueOf(objList.get(j)));
                } else if (types[j] == Date.class) {
                    obj_list.add(DateUtil.parseToDate(objList.get(j)));
                } else if (types[j] == Boolean.class) {
                    obj_list.add(Boolean.valueOf(objList.get(j)));
                    // TO DO 各种扩展
                }

            }
            result[i] = obj_list.toArray();
        }
        return result;
    }
}
  • 读取csv参数文件工具类 CsvUtil.java
package com.billJiang.framework.utils;

import com.billJiang.framework.base.pojo.CsvPOJO;
import com.billJiang.framework.base.pojo.CsvRow;
import org.springframework.core.io.Resource;
import org.supercsv.io.CsvMapReader;
import org.supercsv.io.ICsvMapReader;
import org.supercsv.prefs.CsvPreference;

import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * billJiang http://blog.csdn.net/jrn1012
 */
public class CsvUtil {
    public static CsvPOJO getCaseList(String fileName) {
        CsvPOJO pojo = null;
        Resource[] resources = ConfigurationUtil.getAllResources("/**/" + fileName);
        if (resources == null || resources.length == 0) {
            throw new RuntimeException("CSV文件《" + fileName + "》没有找到!");
        }
        // for(Resource resouce:resources){
        // if(fileName.equals(resouce.getFilename())){
        try {
            pojo = readWithCsvMapReader(resources[0].getFile().getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
        // }
        // }
        return pojo;
    }

    private static CsvPOJO readWithCsvMapReader(String file) throws Exception {
        CsvPOJO csvPojo = new CsvPOJO();
        Map<String, String> readMap = null;
        ICsvMapReader mapReader = null;
        try {
            mapReader = new CsvMapReader(new FileReader(file), CsvPreference.STANDARD_PREFERENCE);
            String[] headers = mapReader.getHeader(true);
            List<CsvRow> rows = new ArrayList<CsvRow>();
            while ((readMap = mapReader.read(headers)) != null) {
                CsvRow row = new CsvRow();
                List<String> columns = new ArrayList<String>();
                for (String h : headers) {
                    if (!StrUtil.isEmpty(h)) {
                        columns.add(readMap.get(h));
                    }
                }
                row.setCols(columns);
                rows.add(row);
            }
            csvPojo.setHeaders(headers);
            csvPojo.setRows(rows);

        } finally {
            if (mapReader != null) {
                mapReader.close();
            }
        }
        return csvPojo;
    }
}
  • csv数据接口 CsvPOJO.java
package com.billJiang.framework.base.pojo;

import java.util.List;


public class CsvPOJO {
    private String[] headers;
    private List<CsvRow> rows;

    public String[] getHeaders() {
        return headers;
    }

    public void setHeaders(String[] headers) {
        this.headers = headers;
    }

    public List<CsvRow> getRows() {
        return rows;
    }

    public void setRows(List<CsvRow> rows) {
        this.rows = rows;
    }

}
  • csv数据接口 CsvRow.java
package com.billJiang.framework.base.pojo;

import java.util.List;

public class CsvRow {
    private List<String> cols;

    public List<String> getCols() {
        return cols;
    }

    public void setCols(List<String> cols) {
        this.cols = cols;
    }
}
  • 测试类 DemoTest.java
package com.test.demo;

import com.billJiang.framework.testng.BaseTest;
import org.testng.Assert;
import org.testng.annotations.Test;


public class DemoTest extends BaseTest {

    @Test(dataProvider = "dataProvider", groups = { "function-test" })
    public void testArea(String caseId, Double w, String l, String h, String check) {
        Assert.assertEquals(w * Double.parseDouble(l) + Double.parseDouble(h), Double.parseDouble(check));
    }
}
  • 参数文件 DemoTest_testArea.csv
id,length,width,height,result
001,1,2,3,5
002,1,2,4,6
003,1,2,5,7
004,1,2,6,5
  • 测试类 UserTest.java
package com.test.demo;

import com.cnpc.framework.base.entity.User;
import com.cnpc.framework.base.service.UserService;
import com.cnpc.framework.testng.BaseTest;
import org.testng.Assert;
import org.testng.annotations.Test;

import javax.annotation.Resource;

public class UserTest extends BaseTest {

    @Resource
    private UserService userService;

    @Test(dataProvider = "dataProvider", groups = { "function-test" })
    public void checkUserExist(String code, String loginname) {
        System.out.println(code + "-----" + loginname);
        User user = userService.getUserByLoginName(loginname);
        Assert.assertNotNull(user);
    }
}
  • 参数文件 UserTest_checkUserExist.csv
id,loginName
001,jrn
002,tester
004,qqqfr
  • 配置文件 RootSuit.xml
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
    <test name="DataProviderTest">
        <groups>
            <run>
                <include name="function-test"/>
                <exclude name="master-test"/>
                <exclude name="unit-test"/>
            </run>
        </groups>
        <classes>
            <class name="com.test.demo.DemoTest" group="function-test"/>
            <class name="com.test.demo.UserTest" group="function-test"/>
        </classes>
    </test>
</suite>

右键RootSuit.xml可运行测试,并在控制台输出测试结果,也可在DemoTest或者UserTest分别运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值