TestNG利用Excel做数据驱动

发表于:2020-1-23 09:35

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

 作者:迈阿密小白    来源:简书

  背景
  自动化测试过程中,数据驱动这一环节是无法避免的。为了降低后期的维护成本,数据驱动是一个有效的解决方案。TestNG中常用的数据驱动注解是 @DataProvider ,该方法返回一个Object[][]。
  实践
  简单的数据驱动
  举个例子:一个简单的登录接口,大致代码如下:
public class Login {
public static boolean isLogin = false;
/**
* 模拟登陆校验方法
* @param name 用户名
* @param pwd 密码
* @return 登陆返回信息
*/
public String userLogin(String name,String pwd){
if(name == null || name.equals("") || pwd ==null || pwd.equals("")){
System.out.println("用户名或密码为空");
isLogin = false;
return "用户名或密码不能为空";
}else if (name == "admin" || name.equals("admin")){
System.out.println("管理员");
isLogin = true;
return "欢迎管理员";
}else{
System.out.println("正常用户");
isLogin = true;
return "欢迎"+name;
}
}
public static void main(String[] args){
Login login = new Login();
login.userLogin("","");
}
}
  为了测试这个接口,我们大致准备了如下用例:
  简单的实现数据驱动方法:
  新建一个Loginparams.java
public class LoginParams {
/**
* 提供用户登陆测试方法数据
* @return
*/
@DataProvider
public Object[][] getUsers(){
return new Object[][]{
{"zhangsan","123456","欢迎zhangsan"},
{"lisi","","用户名或密码不能为空"},
{"","","用户名或密码不能为空"},
{"admin","123456","欢迎管理员"}
};
}
  在测试用例
public class LoginTest {
@Test(dataProvider = "getUsers", dataProviderClass = LoginParams.class)
public void testLogin(String name1, String pwd1, String expect1){
Login login = new Login();
String ac = login.userLogin(name1,pwd1);
Assert.assertEquals(ac,expect1);
}
}
  运行结果如下:
  利用外部数据源
  常见的外部数据源,一般讲数据存在db中,卸载xml/txt/yaml/excel中等等。
  这边以excel为例,读取excel中的数据。
  大致思路:
  先用POI读取excel。解析读取数据,返回list,返回Object[][]即可
  备注:这边主要参考了Refain的文章,有兴趣可以去原博看看
  主要代码如下:
public class ReadExcelUtil {
/**
* read excel
* @param
* @return
*/
public static List<Map<String, String>> getExcuteList(String filePath) {
Workbook wb = null;
Sheet sheet = null;
Row row = null;
List<Map<String, String>> list = null;
String cellData = null;
String columns[] = {"name", "pwd", "exp","pro","num","res"};
wb = readExcel(filePath);
if (wb != null) {
//用来存放表中数据
list = new ArrayList<Map<String, String>>();
sheet = wb.getSheetAt(0);
int rownum = sheet.getPhysicalNumberOfRows();
row = sheet.getRow(0);
int colnum = row.getPhysicalNumberOfCells();
for (int i = 1; i < rownum; i++) {
Map<String, String> map = new LinkedHashMap<String, String>();
row = sheet.getRow(i);
if (row != null) {
for (int j = 0; j < colnum; j++) {
cellData = (String) getCellFormatValue(row.getCell(j));
map.put(columns[j], cellData);
}
} else {
break;
}
list.add(map);
}
}
return list;
}
/**
* 判断excel文件的类型
*
* @param filePath
* @return
*/
public static Workbook readExcel(String filePath) {
Workbook wb = null;
if (filePath == null) {
return null;
}
String extString = filePath.substring(filePath.lastIndexOf("."));
InputStream is = null;
try {
is = new FileInputStream(filePath);
if (".xls".equals(extString)) {
return wb = new HSSFWorkbook(is);
} else if (".xlsx".equals(extString)) {
return wb = new XSSFWorkbook(is);
} else {
return wb = null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return wb;
}
public static Object getCellFormatValue(Cell cell) {
Object cellValue = null;
if (cell != null) {
//判断cell类型
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC: {
cellValue = String.valueOf(cell.getNumericCellValue());
break;
}
case Cell.CELL_TYPE_FORMULA: {
//判断cell是否为日期格式
if (DateUtil.isCellDateFormatted(cell)) {
//转换为日期格式YYYY-mm-dd
cellValue = cell.getDateCellValue();
} else {
//数字
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
}
case Cell.CELL_TYPE_STRING: {
cellValue = cell.getRichStringCellValue().getString();
break;
}
default:
cellValue = "";
}
} else {
cellValue = "";
}
return cellValue;
}
  在Loginparams.java文件中,数据驱动这样实现
@DataProvider
public Object[][] dataMethod(){
List<Map<String, String>> result = ReadExcelUtil.getExcuteList("E:\\Xunit\\src\\test\\java\\LoginData\\bug.xlsx");
Object[][] files = new Object[result.size()][];
for(int i=0; i<result.size(); i++){
files[i] = new Object[]{result.get(i)};
}
return files;
}
  测试一下:
@Test(dataProvider = "dataMethod",dataProviderClass = LoginParams.class)
public void testBuy2(HashMap<String,String> data){
System.out.println(data.get("name")+data.get("pwd"));
String s = login.userLogin(data.get("name"),data.get("pwd"));
Assert.assertEquals(s,data.get("exp"));
int pro = Integer.parseInt(data.get("pro").substring(0,(data.get("pro").length()-2)));
int buynum = Integer.parseInt(data.get("num").substring(0,(data.get("num").length()-2)));
int res = shopping.buys(pro,buynum);
int exp = Integer.parseInt(data.get("res").substring(0,(data.get("res").length()-2)));
Assert.assertEquals(res,exp);
}
  由于返回的结果是string类型,而且后面带小数点,所以这边加了自动截取后两位
  最终运行结果如下:
  
excel.png
   上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

精彩评论

  • bachelor2018
    2020-1-31 10:11:42

    白盒测试需要深刻理解代码逻辑,对测试人员要求较高,具有一定的挑战性。
    不过这个挑战对于测试人员价值的提升是值得的。

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号