背景
数据驱动是我们写自动化脚本非常常用的技术,而Testng中数据驱动常用的注解是 @DataProvider,但是这个方法必须返回一个Object[][]。最近常有学生问起,如果通过外部文件作为数据源,从而实现数据驱动。 例如数据源为Excel时,如何读取excel完成数据驱动呢? 简单思路就是,读取excel数据,excel数据第一行作为map的Key其它行为值,放入map并返回。 @DataProvider 注解对应方法去获取调读取excel方法,拿到返回的Object[][],其余都一样使用。
ps.代码是不值钱的,关键是解决问题的思路。
Demo
话不多说,直接上Demo。
1.准备Excel数据
- 新建maven工程,并导入 poi相关包:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.15</version> </dependency>
3.读取Excel数据,并放入Map中返回。
/** * @param file 读取某个excel文件 * @return Object */ public Object[][] testData(String file) { ArrayList<String> arrkey = new ArrayList<String>(); Workbook workbook = WorkBookEhi.getWorkbook(file); Sheet sheet = workbook.getSheetAt(0); // 获取总行数 int rowTotalNum = sheet.getLastRowNum()+1; // 总列数 int columns = sheet.getRow(0).getPhysicalNumberOfCells(); HashMap<String, String>[][] map = new HashMap[rowTotalNum - 1][1]; // 对数组中所有元素hashmap进行初始化 if (rowTotalNum > 1) { for (int i = 0; i < rowTotalNum - 1; i++) { map[i][0] = new HashMap(); } } else { log.error("测试的Excel" + file + "中没有数据"); } // 获得首行的列名,作为hashmap的key值 for (int c = 0; c < columns; c++) { String cellvalue = CellUnit.getCellValue(sheet, 0, c); arrkey.add(cellvalue); } // 遍历所有的单元格的值添加到hashmap中 for (int r = 1; r < rowTotalNum; r++) { for (int c = 0; c < columns; c++) { String cellvalue = CellUnit.getCellValue(sheet, r, c); map[r - 1][0].put(arrkey.get(c), cellvalue); } } return map; }
当然这个这里面的getWorkbook()方法我也是经过封装了,代码如下:
/** * 创建 workbook * * @param filePath excel文件路径 * @return Workbook 对象 * @throws IOException */ public static Workbook getWorkbook(String filePath) { Workbook wb = null; try { if (filePath.endsWith(".xls")) { File file = new File(filePath); InputStream is = new FileInputStream(file); wb = new HSSFWorkbook(is); } else if (filePath.endsWith(".xlsx") || filePath.endsWith(".xlsm")) { wb = new XSSFWorkbook(filePath); } } catch (IOException e) { e.printStackTrace(); } return wb; } CellUnit.getCellValue()方法封装如下: /** * 通过sheet 行号和列返回值 * * @param sheet sheet name * @param rowNum 行号 * @param cellNum 列号 * @return */ public static String getCellValue(Sheet sheet, int rowNum, int cellNum) { Cell cell = sheet.getRow(rowNum).getCell(cellNum); String value = CellUnit.getCellValue(cell); return value; } CellUnit.getCellValue() 方法封装如下: /** * 把不同类型的单元格转换成字符串,并返回 * * @param cell cell * @return 当个单元格值 */ public static String getCellValue2(Cell cell) { String value = ""; switch (cell.getCellTypeEnum()) { case STRING: value = String.valueOf(cell.getRichStringCellValue()); return value; case NUMERIC: value = String.valueOf(cell.getNumericCellValue()); return value; case BOOLEAN: value = String.valueOf(cell.getBooleanCellValue()); return value; case FORMULA: value = String.valueOf(cell.getCellFormula()); return value; case ERROR: value = String.valueOf(cell.getErrorCellValue()); return value; case BLANK: return value; default: log.warn("未知该单元格类型"); return value; } }
4.Testng 使用数据
@DataProvider(name = "testData") public Object[][] data() { TestCaseExcel testcase = new TestCaseExcel(); return testcase.testData(file); } @Test(dataProvider = "testData") public void testCase(HashMap<String, String> data) { String fileName = data.get("excelName"); String bpSheetName = data.get("Benefits Package Sheet"); int bpRowNum = Integer.parseInt(data.get("BP sheet RowNum")); String csvSheetName = data.get("Cost Share Variances Sheet"); int csvRowNum = Integer.parseInt(data.get("CSV Sheet RowNum")); String hiosPlanID = data.get("HIOS Plan ID"); String isPass = data.get("isPass");
作者:博客已迁移I米阳
链接:https://www.jianshu.com/p/895e4c118db9
来源:简书