2016-08-08java
什麼是數據驅動?簡答的理解就是測試數據決定了測試結果,這就是所謂數據驅動。數據驅動包含了數據,他就是測試數據,在自動化領域裏,提倡數據分離,也就是說,測試用例和測試數據是分開(存儲)的。 apache
在本框架設計中,採用的是Excel存儲測試數據。api
源代碼:autotestDataDriver.zip框架
在原來的框架下更改,以下圖所示ide
下面代碼中,紅色字體顯示出更改先後變化。更改後數據不是寫在代碼中,而是從excel中讀取。那麼怎麼讓讀取數據,且對應用例呢?測試
先看看如何設計excel:字體
excel的表名以模塊名命名。excel中,有個sheet,名字爲'001',對應用例編號,和設計用例的的類名第二部分是對應的,也就是說一個sheet就是一個測試用例的數據。在執行測試用例的時候,經過模塊名字找到對應的excel,而後再根據對應的用例編號找到對應的sheet,最後在讀取excel數據。 this
經過數據提供者(@DataProvider)來傳遞給測試用例,這裏將數據提供者代碼放置在BaseParpare.java中,目的是爲了每次運行一個用例都會讀取對應的測試用例。spa
/** * 測試數據提供者 - 方法 * */ @DataProvider(name = "testData") public Iterator<Object[]> dataFortestMethod() throws IOException { String moduleName = null; // 模塊的名字 String caseNum = null; // 用例編號 String className = this.getClass().getName(); int dotIndexNum = className.indexOf("."); // 取得第一個.的index int underlineIndexNum = className.indexOf("_"); // 取得第一個_的index if (dotIndexNum > 0) { moduleName = className.substring(24, className.lastIndexOf(".")); // 取到模塊的名稱 } if (underlineIndexNum > 0) { caseNum = className.substring(underlineIndexNum + 1, underlineIndexNum + 4); // 取到用例編號 } //將模塊名稱和用例的編號傳給 ExcelDataProvider ,而後進行讀取excel數據 return new ExcelDataProvider(moduleName, caseNum); }
ExcelDataProvider.java,代碼以下:設計
package com.demo.test.utils; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; import org.apache.log4j.Logger; import org.testng.Assert; /** * @author young * @description: 讀取Excel數據<br> * 說明:<br> * Excel放在Data文件夾下<br> * Excel命名方式:測試類名.xls<br> * Excel的sheet命名方式:測試方法名<br> * Excel第一行爲Map鍵值<br> */ public class ExcelDataProvider implements Iterator<Object[]> { private Workbook book = null; private Sheet sheet = null; private int rowNum = 0; private int currentRowNo = 0; private int columnNum = 0; private String[] columnnName; private String path = null; private InputStream inputStream = null; public static Logger logger = Logger.getLogger(ExcelDataProvider.class.getName()); /* * @description * 2個參數:<br> * moduleName - 模塊的名稱 * caseNum - 測試用例編號 **/ public ExcelDataProvider(String moduleName, String caseNum) { try { //文件路徑 path = "data/" + moduleName + ".xls"; inputStream = new FileInputStream(path); book = Workbook.getWorkbook(inputStream); // sheet = book.getSheet(methodname); sheet = book.getSheet(caseNum); // 讀取第一個sheet rowNum = sheet.getRows(); // 得到該sheet的 全部行 Cell[] cell = sheet.getRow(0);// 得到第一行的全部單元格 columnNum = cell.length; // 單元格的個數 值 賦給 列數 columnnName = new String[cell.length];// 開闢 列名的大小 for (int i = 0; i < cell.length; i++) { columnnName[i] = cell[i].getContents().toString(); // 第一行的值 // 被賦予爲列名 } this.currentRowNo++; } catch (FileNotFoundException e) { logger.error("沒有找到指定的文件:" + "[" + path + "]"); Assert.fail("沒有找到指定的文件:" + "[" + path + "]"); } catch (Exception e) { logger.error("不能讀取文件: [" + path + "]",e); Assert.fail("不能讀取文件: [" + path + "]"); } } /**是否還有下個內容*/ public boolean hasNext() { if (this.rowNum == 0 || this.currentRowNo >= this.rowNum) { try { inputStream.close(); book.close(); } catch (Exception e) { e.printStackTrace(); } return false; } else { // sheet下一行內容爲空斷定結束 if ((sheet.getRow(currentRowNo))[0].getContents().equals("")) return false; return true; } } /**返回內容*/ public Object[] next() { Cell[] c = sheet.getRow(this.currentRowNo); Map<String, String> data = new HashMap<String, String>(); for (int i = 0; i < this.columnNum; i++) { String temp = ""; try { temp = c[i].getContents().toString(); } catch (ArrayIndexOutOfBoundsException ex) { temp = ""; } data.put(this.columnnName[i], temp); } Object object[] = new Object[1]; object[0] = data; this.currentRowNo++; return object; } public void remove() { throw new UnsupportedOperationException("remove unsupported."); } }
Pom.xml添加jar依賴:
<dependency> <groupId>net.sourceforge.jexcelapi</groupId> <artifactId>jxl</artifactId> <version>2.6.12</version> <scope>provided</scope> </dependency>