在上一篇中,我們實現了post方法請求的封裝和測試,這一篇我們做測試數據的分離。
5.1 測試數據處理思路
5.1.1 測試數據分離
這里我想到,我們之前的測試demo里,全都是在testNG類里去寫入測試請求的相關數據。
如果測試到達一定規模,這樣去維護測試數據會當然是不行的。
比較好的辦法應該是將測試數據分離出來,通過外部文件來管理,然后讀取文件驅動測試。
這個外部文件用Excel來做會比較合適,設計如下:

考慮用表單來驅動請求的方法,暫時寫上了Get,Post,Put和Delete方法。當然其實我還沒有去實現put和delete方法,后續再添加。
表單的內容分別記錄:
- 測試用例編號
- 測試名稱
- 協議
- 接口地址
- 檢查點
- 狀態碼
- key1...keyN傳入參數
之前用到的url這樣的不會輕易變動的數據存放到另一個property文件中去。
5.1.2 配置數據分離
接下來將測試中所用到的配置獨立出去:
在src/main/resource下新建config.properties文件。
Host = https://api.apishop.net/ testData = \\src\\test\\resources\\APIcase.xls
主要用於存放用到的外部文件位置。
5.2 數據讀取和處理
5.2.1 測試基類讀取配置
在項目中src/test/java下新建包com.test.api,創建類TestApi.java,寫入以下內容:
package com.test.api; import java.io.FileInputStream; import java.util.Properties; public class TestAPI { public Properties prop; public String excelPath; public String host; //構造函數 public testAPI() { try {
//數據流的形式讀取配置文件 prop = new Properties(); FileInputStream fis = new FileInputStream(System.getProperty("user.dir")+ "/src/main/resources/config.properties"); prop.load(fis); } catch (Exception e) { e.printStackTrace(); } host = prop.getProperty("Host"); excelPath=prop.getProperty("testData"); } }
把這個類做為我們測試基類,后續在創建測試時只要繼承這個類就可以了。
5.2.2 POI讀取外部Excel
在項目中src/main/java下的test.com.utils包中,新建ExcelProcess類,寫入以下代碼:
package com.test.utils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.CellType; public class ExcelProcess {public static Object[][] proessExcel(String filePath,int sheetId) throws IOException{ //數據流讀入excel File file = new File(System.getProperty("user.dir")+filePath); FileInputStream fis = new FileInputStream(file); HSSFWorkbook wb = new HSSFWorkbook(fis); //讀取特定表單並計算行列數 HSSFSheet sheet = wb.getSheetAt(sheetId); int numberOfRow = sheet.getPhysicalNumberOfRows(); int numberOfCell = sheet.getRow(0).getLastCellNum(); //將表單數據處理存入dtt對象 Object[][] dttData = new Object[numberOfRow][numberOfCell]; for(int i=0;i<numberOfRow;i++){ if(null==sheet.getRow(i)||"".equals(sheet.getRow(i))){ continue; } for(int j=0;j<numberOfCell;j++) { if(null==sheet.getRow(i).getCell(j)||"".equals(sheet.getRow(i).getCell(j))){ continue; } HSSFCell cell = sheet.getRow(i).getCell(j); cell.setCellType(CellType.STRING); dttData[i][j] = cell.getStringCellValue(); } } return dttData; } }
5.2.3 jsonPath處理反饋信息
在本篇第一部分的設計中,我將每個測試的驗證點寫在了外部excel文件里,基本的想法是,從反饋信息內拿出相應的鍵值,與excel內的驗證點相比較。
所以這里我需要改造之前的JSONParser,去實現特定鍵值對的獲取。這里我用jsonPath去實現:
package com.test.utils; import com.alibaba.fastjson.JSONObject; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.ReadContext; import net.minidev.json.JSONArray; public class JSONParser { public boolean isResponseCorrect(JSONObject jo,String checkpoint,String passValue){
//用jsonpath處理json,獲取result中特定鍵值 ReadContext context = JsonPath.parse(jo); JSONArray result = context.read("$.result.."+checkpoint); String resultString = result.get(0).toString(); if(resultString.equals(passValue)){ return true; }else{ return false; } } }
jsonpath本文不再贅述,感興趣的可以去搜索一下相關教程。本段代碼也只是簡單的用".."去實現對result元素下的所有元素進行遍歷和匹配。
5.3 實現測試類
5.3.1 TestNG類實現測試
重寫TestPost測試類,改寫后代碼如下:
package com.test.api; import org.testng.annotations.Test; import com.alibaba.fastjson.JSONObject; import com.test.client.RestfulClient; import com.test.utils.ExcelProcess; import com.test.utils.JSONParser; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.message.BasicNameValuePair; import org.testng.Assert; import org.testng.annotations.BeforeClass; public class TestPost extends TestAPI{ RestfulClient client; JSONObject responseBody; int responseCode; String url; String postBody; Object[][] excelData; HashMap<String, String> hashHead; @BeforeClass public void setup() throws ClientProtocolException, IOException { //讀取用例excel excelData = ExcelProcess.proessExcel(excelPath, 1); //實例化client client = new RestfulClient(); //設置好請求頭部 hashHead = new HashMap<String, String>(); hashHead.put("Content-Type", "application/x-www-form-urlencoded"); } @Test public void testPostRequest() throws ClientProtocolException, IOException { //從第二行開始遍歷表單,跳過表頭 for(int i=1;i<excelData.length;i++){ //從特定位置讀取測試數據 String address = excelData[i][3].toString(); url = host+address; String checkPoint = excelData[i][4].toString(); String checkValue = excelData[i][5].toString(); //用NameValuePair存儲所有請求參數 List<NameValuePair> keys = new ArrayList<NameValuePair>(); for(int j=7;j<excelData[i].length-2;j=j+2){ //因為每種請求的參數個數不確定,在這里進行非空判斷 if(excelData[i][j]==null){ break; } NameValuePair pair = new BasicNameValuePair(excelData[i][j].toString(),excelData[i][j+1].toString()); keys.add(pair); } //發出請求 client.sendPost(url, keys, hashHead); responseBody = client.getBodyInJSON(); responseCode = client.getCodeInNumber(); JSONParser jParser = new JSONParser(); boolean result = jParser.isResponseCorrect(responseBody, checkPoint, checkValue); //斷言判斷結果 Assert.assertTrue(result); Assert.assertEquals(responseCode, 200); } } }
測試類繼承前文的TestAPI類,setup方法讀取excel表單,設置好請求頭部,testPostRequest發送請求並分析結果。
5.3.2 測試結果
用以下外部測試數據驅動測試:

可以看到,測試用例中包含了兩個不同的接口測試,測試均通過。
注:
在TestNG測試類里,在讀取測試數據時,我采取的是讀取固定位置的參數,顯然這樣的處理在代碼健壯性上是比較差的,可以進一步改進。
另外測試數據中的protocol我只是進行了設計,還沒有真正處理。
