数据分离
问题:数据源写在case类中,数据和代码耦合度高
一般接口测试的数据源我们可以使用别的方式管理,比如excel,那么如何将excel中的数据源转换成testng中DataProvider注解所需要的Object[][]二维数组呢?
拆分为2个过程:
1、数据源读取
2、数据源转二维数组
引入excel处理的依赖poi
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
为什么要引入poi依赖?因为要使用poi已经封装好excel对象,从导包中可以了解到引用对象的依赖来源
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
excel数据读取
假设excel数据源格式为下图实例,名称为:registercase.xls
把excel文件复制进入\src\test\resources文件夹下
utils工具包里新建一个ExcelUtils类,用来处理excel操作。
读取excel步骤拆解:
1、打开excel文件(输入文件流)
2、创建workbook(excel工作薄)
3、获取sheet(excel工作页)
4、获取row(excel行)
5、获取cell(excel单元格)
public class ExcelUtils {
public static void main(String[] args) throws Exception {
//写个main测试一下read方法是否能将想获取的内容都打印出来
read();
}
public static void read() throws Exception {
// 1、打开excel文件(输入文件流)
FileInputStream fis = new FileInputStream("src\\test\\resources\\registercase.xls");
// 2、创建workbook(excel工作薄)
Workbook workbook = WorkbookFactory.create(fis);
// 3、获取sheet(excel工作页)
Sheet sheet = workbook.getSheetAt(0);
// 4、获取row(excel行),先要获取到sheet页的行数lastRowNum
int lastRowNum = sheet.getLastRowNum();
// 在循环获取每一行,注意循环要去掉第一行表头
for(int i=1;i<lastRowNum;i++) {
Row row = sheet.getRow(i);
// 5、获取cell(excel单元格),先要获取每一行的单元格数
int lastCellNum = row.getLastCellNum();
// 在循环每行的单元格
for(int j=0;j<lastCellNum;j++) {
// 获取想要的指定列,根据自己接口入参excel灵活设置,根据实例excel想要获取2、3、4列(是excel的url接口地址、method请求方式、request请求报文)
if(j==2 || j==3 ||j==4) {
// 获取[i][j]单元格值,MissingCellPolicy.CREATE_NULL_AS_BLANK设置下null值避免报空异常
Cell cell = row.getCell(j,MissingCellPolicy.CREATE_NULL_AS_BLANK);
// 设置单元格值为String类型
cell.setCellType(CellType.STRING);
// 获取单元格的String值
String stringCellValue = cell.getStringCellValue();
// 打印单元格值
System.out.print(stringCellValue+",");
}
}
System.out.println();
}
// 6、关流
fis.close();
}
}
解决了excel读取的问题,再接着思考:
问题1:如何把读取到的excel中的接口地址、请求方式、请求入参给到注册案例类中的DataProvider里?
因为DataProvider是要得到一个二维数组,所以需要把读取的内容转换成二维数组
问题2:二维数组的[n][m]中的n和m如何取值?
n其实就是要执行几次案例,有多少组数据源,=lastRowNum
m就是每行单元格数,目前是自定义抽取的3列,对应每行的3个单元格
excel数据转成二维数组
修改ExcelUtils类,让read方法返回值从void变成二维数组,所以要在read方法中定义一个二维数组Object[n][m],在给数组赋值,最后返回,需要在上一个代码基础上新增3行代码
public class ExcelUtils {
public static void main(String[] args) throws Exception {
//read方法改造完后测试一下是否转二维数组成功
Object[][] datas = read();
for(Object[] e:datas) {
System.out.println(Arrays.toString(e));
}
}
public static Object[][] read() throws Exception {
FileInputStream fis = new FileInputStream("src\\test\\resources\\registercase.xls");
Workbook workbook = WorkbookFactory.create(fis);
Sheet sheet = workbook.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
// 1、定义一个二维数组
Object[][] datas = new Object[lastRowNum][3];
for(int i=1;i<lastRowNum;i++) {
Row row = sheet.getRow(i);
int lastCellNum = row.getLastCellNum();
for(int j=0,index=0;j<lastCellNum;j++) {
if(j==2 || j==3 ||j==4) {
Cell cell = row.getCell(j,MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell.setCellType(CellType.STRING);
String stringCellValue = cell.getStringCellValue();
System.out.print(stringCellValue+",");
// 2、把每个单元格放入二维数组
datas[i-1][index++] = stringCellValue;
}
}
System.out.println();
}
fis.close();
// 3、返回二维数组
return datas;
}
}
捕获异常
问题:read方法是直接抛异常,会导致每次使用时其他方法都要跟着抛异常,所以需要修改ExcelUtils类里read方法捕获异常
// 1、去掉方法后的throws Exception
public static Object[][] read() {
// 3、修改定义变量作用域,否则返回值会报错
FileInputStream fis = null;
Object[][] datas = null;
// 2、加try catch捕获异常
try {
fis = new FileInputStream("src\\test\\resources\\registercase.xls");
Workbook workbook = WorkbookFactory.create(fis);
Sheet sheet = workbook.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
datas = new Object[lastRowNum][3];
for(int i=1;i<lastRowNum;i++) {
Row row = sheet.getRow(i);
int lastCellNum = row.getLastCellNum();
for(int j=0,index=0;j<lastCellNum;j++) {
if(j==2 || j==3 ||j==4) {
Cell cell = row.getCell(j,MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell.setCellType(CellType.STRING);
String stringCellValue = cell.getStringCellValue();
System.out.print(stringCellValue+",");
datas[i-1][index++] = stringCellValue;
}
}
System.out.println();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
// 4、关流需要判断流是否为空
if(fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return datas;
}
注册案例类RegisterCase的@DataProvider修改成excel读取数据,实现数据和代码分离
@DataProvider
public Object registerDatas() {
//二维数组来源于excel数据源,直接调用封装好的ExcelUtils类的read方法
Object[][] Datas = ExcelUtils.read();
return Datas;
}
通过testng test运行程序,看接口是否均按照excel入参去正常调用