Spring集成TestNG参数化批量测试

发表于:2018-8-16 11:10

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:推敲    来源:CSDN

  介绍
  在TestNG中,一个强大的功能是参数测试。在大多数情况下,你会遇到这样一个场景,业务逻辑需要一个巨大的不同数量的测试。参数测试,允许开发人员运行同样的测试,一遍又一遍使用不同的值。
  TestNG让你直接传递参数测试方法两种不同的方式:
  testng.xml配置参数:在testng.xml文件中定义的简单参数,然后在源文件中引用这些参数
  DataProvider注解: 当你需要通过复杂的参数或参数需要创建从Java(复杂的对象,对象读取属性文件或数据库等..),在这种情况下,可以将参数传递使用数据提供者。数据提供者@DataProvider的批注的方法。这个注解只有一个字符串属性:它的名字。如果不提供名称,数据提供者的名称会自动默认方法的名称。数据提供者返回一个对象数组。
  而本文介绍在Spring中集成TestNG测试框架,是以CSV外部输入参数为参数,通过DataProvider注解生成TestNG测试所需外部参数:
  说明
  文件结构
  
  运行结果
  
  代码示例
  在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分别运行

   上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号