TestNG利用Excel做数据驱动
2019-01-05 本文已影响2人
迈阿密小白
背景
自动化测试过程中,数据驱动这一环节是无法避免的。为了降低后期的维护成本,数据驱动是一个有效的解决方案。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("","");
}
}
为了测试这个接口,我们大致准备了如下用例:
用户名 | 密码 | 期望结果 |
---|---|---|
" " | " " | 用户名或密码不能为空 |
admin | " " | 用户名或密码不能为空 |
wade | " " | 用户名或密码不能为空 |
wade | 123 | 欢迎wade |
admin | 123 | 欢迎管理员 |
" " | 123 | 用户名或密码不能为空 |
简单的实现数据驱动方法:
新建一个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);
}
}
运行结果如下:
res.png
利用外部数据源
常见的外部数据源,一般讲数据存在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