天天看點

接口自動化實作

一.實作架構:

 java+maven+testng+reportNG+jenkins架構

二.架構原理:

使用腳本發送HTTP請求傳回接口的響應結果,并将代碼存放在svn,Git中,jenkins可以設定測試的時間自動擷取代碼,編輯和運作。

三.環境部署和安裝:

1.安裝JDK1.8,配置相關的環境變量;

2.安裝eclipse;

3.在eclipse中安裝maven,svn,testng插件;

四.詳細實作:

1.詳情:

接口自動化實作

2.封裝http請求方法:

package com.jdapi.util;

/**

* HttpRequest.java Created on

* @author

* @version 1.0

* 封裝GET,PUT,POST,Delete請求

*/

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.Map;

import java.util.Objects;

import org.apache.log4j.Logger;

import okhttp3.Headers;

import okhttp3.MediaType;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.RequestBody;

public class HttpRequest {

private Logger logger = Logger.getLogger(this.getClass());

/**

* @param path

* @param query

* @param header

* @param json

* query拼接在請求位址後面,類似url?query1=value1&query2=value2

* header為空則填null,不為空則直接調用getOfflineHeader方法

* json參數從excel表格中擷取json格式的字元串

* @return

* @throws IOException

*/

public String sendPost(String path,Map<String,String> query,Map<String,String> header,String json) throws IOException{

OkHttpClient client = new OkHttpClient();

StringBuilder url = new StringBuilder(path);

Request request = null;

String result = "";

if (Objects.nonNull(query) && Objects.nonNull(json) && Objects.isNull(header)) {

url.append("?");

query.forEach((k, v)->{

url.append(k).append("=").append(v).append("&");

});

String temporaryUrl = url.substring(0,url.length()-1);

url.setLength(0);

url.append(temporaryUrl);

RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);

body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);

request = new Request.Builder()

.url(url.toString())

.post(body)

.build();

result = client.newCall(request).execute().body().string();

}

if(Objects.nonNull(query) && Objects.isNull(header) && Objects.isNull(json)){

BufferedReader in = null;

OutputStreamWriter out = null;

StringBuilder rs = new StringBuilder();

StringBuilder realUrl = new StringBuilder(path);

try {

url.append("?");

query.forEach((k, v)->{

url.append(k).append("=").append(v).append("&");

});

String temporaryUrl = url.substring(0,url.length()-1);

url.setLength(0);

url.append(temporaryUrl);

URL requestUrl = new URL(realUrl.toString());

HttpURLConnection conn = (HttpURLConnection)requestUrl.openConnection();

conn.setRequestMethod("POST");

conn.setDoOutput(true);

conn.setDoInput(true);

//設定連接配接逾時時間和讀取逾時時間

conn.setConnectTimeout(10000);

conn.setReadTimeout(10000);

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

out = new OutputStreamWriter(conn.getOutputStream());

out.flush();

out.close();

// 取得輸入流,并使用Reader讀取

in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

String line;

while ((line = in.readLine()) != null) {

rs.append(line);

}

} catch (Exception e) {

e.printStackTrace();

}

//關閉輸出流、輸入流

finally{

try{

if(out!=null){

out.close();

}

if(in!=null){

in.close();

catch(IOException ex){

ex.printStackTrace();

result = rs.toString();

if(Objects.nonNull(query) && Objects.nonNull(json) && Objects.nonNull(header)){

url.append(temporaryUrl);

body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);

.url(url.toString())

.headers(Headers.of(header))

.post(body)

.build();

result = client.newCall(request).execute().body().string();

if(Objects.isNull(query) && Objects.nonNull(json) && Objects.nonNull(header)){

RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);

body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);

request = new Request.Builder()

.url(url.toString())

.headers(Headers.of(header))

.post(body)

.build();

return client.newCall(request).execute().body().string();

if(Objects.isNull(query) && Objects.nonNull(json) && Objects.isNull(header)){

body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);

.url(url.toString())

.post(body)

.build();

return result;

}

*

* @return result 請求結果

public String sendGet(String path,Map<String,String> query,Map<String,String> header,String json) throws IOException{

String requestUrl = null;

String result = null;

if(url.toString().contains("\"\"")){

requestUrl = url.toString().replace("\"\"", "");

}else{

requestUrl = url.toString();

}

.url(requestUrl)

if(Objects.nonNull(query) && Objects.nonNull(header) && Objects.nonNull(json)){

* @param url

* 請求位址:url/path1/path2,請求json字元串放在body中

* @return result

public String sendPut(String url,String[] path,String json) throws IOException{

OkHttpClient client = new OkHttpClient();

StringBuilder realUrl = new StringBuilder(url);

RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),"");

//如果請求中帶有query參數,則拼接在path後面

if(Objects.nonNull(path)){

for(int i=0;i<path.length;i++){

realUrl.append("/").append(path[i]);

}

logger.debug("實際請求位址是:"+realUrl.toString());

Request request = new Request.Builder()

.url(realUrl.toString())

.put(body)

.build();

return client.newCall(request).execute().body().string();

* 請求位址:url/path1/path2

public String sendDelete(String url,String[]path) throws IOException{

return client.newCall(request).execute().body().string();

public interface OnResponseCallback {

void onResponse(String str);

}

public String sendPostWithUrlAndQuery(String path,Map<String,String> query){

BufferedReader in = null;

OutputStreamWriter out = null;

StringBuilder result = new StringBuilder();

StringBuilder url = new StringBuilder(path);

try {

url.append("?");

query.forEach((k, v)->{

url.append(k).append("=").append(v).append("&");

});

String temporaryUrl = url.substring(0,url.length()-1);

url.setLength(0);

url.append(temporaryUrl);

URL realUrl = new URL(url.toString());

HttpURLConnection conn = (HttpURLConnection)realUrl.openConnection();

conn.setRequestMethod("POST");

conn.setDoOutput(true);

conn.setDoInput(true);

//設定連接配接逾時時間和讀取逾時時間

conn.setConnectTimeout(10000);

conn.setReadTimeout(10000);

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

out = new OutputStreamWriter(conn.getOutputStream());

out.flush();

out.close();

// 取得輸入流,并使用Reader讀取

in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

String line;

while ((line = in.readLine()) != null) {

result.append(line);

}

} catch (Exception e) {

e.printStackTrace();

}

//關閉輸出流、輸入流

finally{

try{

if(out!=null){

out.close();

}

if(in!=null){

in.close();

catch(IOException ex){

ex.printStackTrace();

return result.toString();

}

 3.json解析:

import com.google.gson.GsonBuilder;

public class AnalyzeJson {

private static Logger logger = Logger.getLogger(AnalyzeJson.class);

* 封裝了響應結果中帶有list數組和data不同情況下

* 取出return_msg字段值的方法

* responseResult 是請求響應結果

* dataType 表示return_data傳回字段中是否包括數組,如果有數組則此參數傳list,不包括數組則此參數傳data,缺失data字段則傳emptyData

public static String getresultmsg(String responseResult,String responseType){

try{

if(responseType.equals("list")){

ListResponseResult resultObj = new GsonBuilder().create().fromJson(responseResult,ListResponseResult.class);

return resultObj.resultmsg();

}else if(responseType.equals("data")){

ResponseResult resultObj = new GsonBuilder().create().fromJson(responseResult,ResponseResult.class);

}catch(Exception e){

e.printStackTrace();

logger.debug("響應結果類型傳參有誤,請輸入list,data,emptyData中的一種類型");

return null;

* 根據接口請求傳回數組分類,解析傳回字段

* @param responseResult

* @param dataType

* @param field

* @throws Exception

public static String getValue(String responseResult,String dataType,String field) throws Exception{

if(responseResult.length() != 0){

if(dataType.equals("list")){

ListResponseResult resultObj = new GsonBuilder().create().fromJson(responseResult,ListResponseResult.class);

for(Map<String, Object> o : resultObj.getData()){

return (String)o.get(field);

}

}else if(dataType.equals("data")){

ResponseResult resultObj = new GsonBuilder().create().fromJson(responseResult,ResponseResult.class);

return resultObj.getData().get(field).toString();

}

}

logger.debug("json字段類型傳參有誤,請輸入list,data,或者null!");

return null;

* 判斷return_data是否傳回空數組,如果為空數組則傳回true,不為空數組則傳回false

public static boolean isReturnDataEmpty(String responseResult,String dataType){

if(responseResult.length() != 0){

if(dataType.equals("list")){

ListResponseResult resultObj = new GsonBuilder().create().fromJson(responseResult, ListResponseResult.class);

if(resultObj.getData().toString().equals("[]")){

return true;

return false;

}else if(dataType.equals("data")){

ResponseResult resultObj = new GsonBuilder().create().fromJson(responseResult, ResponseResult.class);

return true;

4.excel資料讀取:

import java.io.File;

import java.io.FileInputStream;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.DataFormatter;

import org.apache.poi.ss.usermodel.DateUtil;

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;

public class ExcelReader {

private String filePath;

private String sheetName;

private Workbook workBook;

private Sheet sheet;

private List<String> columnHeaderList;

private List<List<String>> listData;

private List<Map<String,String>> mapData;

private boolean flag;

public ExcelReader(String filePath, String sheetName) {

this.filePath = filePath;

this.sheetName = sheetName;

this.flag = false;

this.load();

}

private void load() {

FileInputStream inStream = null;

try {

inStream = new FileInputStream(new File(filePath));

workBook = WorkbookFactory.create(inStream);

sheet = workBook.getSheet(sheetName);

} catch (Exception e) {

e.printStackTrace();

}finally{

try {

if(inStream!=null){

inStream.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

private String getCellValue(Cell cell) {

String cellValue = "";

DataFormatter formatter = new DataFormatter();

if (cell != null) {

switch (cell.getCellType()) {

case Cell.CELL_TYPE_NUMERIC:

if (DateUtil.isCellDateFormatted(cell)) {

cellValue = formatter.formatCellValue(cell);

} else {

double value = cell.getNumericCellValue();

int intValue = (int) value;

cellValue = value - intValue == 0 ? String.valueOf(intValue) : String.valueOf(value);

}

break;

case Cell.CELL_TYPE_STRING:

cellValue = cell.getStringCellValue();

case Cell.CELL_TYPE_BOOLEAN:

cellValue = String.valueOf(cell.getBooleanCellValue());

case Cell.CELL_TYPE_FORMULA:

cellValue = String.valueOf(cell.getCellFormula());

case Cell.CELL_TYPE_BLANK:

cellValue = "";

case Cell.CELL_TYPE_ERROR:

default:

cellValue = cell.toString().trim();

return cellValue.trim();

private void getSheetData() {

listData = new ArrayList<List<String>>();

mapData = new ArrayList<Map<String, String>>();

columnHeaderList = new ArrayList<String>();

int numOfRows = sheet.getLastRowNum() + 1;

for (int i = 0; i < numOfRows; i++) {

Row row = sheet.getRow(i);

Map<String, String> map = new HashMap<String, String>();

List<String> list = new ArrayList<String>();

if (row != null) {

for (int j = 0; j < row.getLastCellNum(); j++) {

Cell cell = row.getCell(j);

if (i == 0){

columnHeaderList.add(getCellValue(cell));

else{

map.put(columnHeaderList.get(j), this.getCellValue(cell));

list.add(this.getCellValue(cell));

}

if (i > 0){

mapData.add(map);

listData.add(list);

flag = true;

public String getCellData(int row, int col){

if(row<=0 || col<=0){

return null;

if(!flag){

this.getSheetData();

}

if(listData.size()>=row && listData.get(row-1).size()>=col){

return listData.get(row-1).get(col-1);

}else{

public String getCellData(int row, String headerName){

if(row<=0){

if(mapData.size()>=row && mapData.get(row-1).containsKey(headerName)){

return mapData.get(row-1).get(headerName);

public Map<String,String> getQueryToMap(int row,String headerName){

String result;

String[] sourceStrArray;

Map<String,String> mp = new HashMap<String,String>();

if(row<=0){

return null;

}

if(!flag){

this.getSheetData();

}

if(mapData.size()>=row && mapData.get(row-1).containsKey(headerName)){

result = mapData.get(row-1).get(headerName);

sourceStrArray = result.split("&");

if(sourceStrArray.length>=2){

for(int i=0;i<sourceStrArray.length;i++){

String[] ary = sourceStrArray[i].split("=");

for(int j=1;j<ary.length;j++){

mp.put(ary[j-1],ary[ary.length-1]);

}

}

}else{

String[] ary = result.split("=");

mp.put(ary[0], ary[ary.length-1]);

}

return mp;

}else{

 5.excel資料:

接口自動化實作

6.測試代碼:

package com.jdapi.testcase;

import org.testng.annotations.Test;

import com.jdapi.util.ExcelReader;

import com.jdapi.util.AnalyzeJson;

import com.jdapi.util.HttpRequest;

import com.jdapi.util.Assertion;

public class NewTest {

private String excelPath = "D:\\testdata\\test.xlsx";

private String sheet = "京東天氣預報接口";

ExcelReader excelReader = new ExcelReader(excelPath, sheet);

HttpRequest httpRequest = new HttpRequest();

AnalyzeJson analyzeJson = new AnalyzeJson();

private String result = "";

@Test

public void test_NewTest() throws Exception

{

result = httpRequest.sendGet(excelReader.getCellData(1, "url"), excelReader.getQueryToMap(1, "query"),null, null);

logger.info("接口響應結果:"+result);

Assertion.verifyEquals(AnalyzeJson.getresultmsg(result, "data"),excelReader.getCellData(1, "expectedResult"));

logger.info("實際結果是:"+AnalyzeJson.getresultmsg(result, "data"));

logger.info("預期結果是:"+excelReader.getCellData(1, "expectedResult"));

}

 7.運作結果:

接口自動化實作
接口自動化實作

 總結:需要學習的知識點為java相關網絡程式設計,例如http請求不同方法的封裝,json的解析以及分層解析,連接配接資料庫操作資料庫,檔案讀取;基本功日志相關;

其中個人認為在實作的過程中難點:

1.json的解析尤其是遇到不同傳回結果,多層實作的時候就比較困難;

2.斷言現在隻是基本的實作和檔案預期結果進行對比判斷;

3.請求頭的封裝;

4.簽名的封裝;

5.接口格式一定要完全統一;

後期優化實作方向:

1.json多層解析;

2.斷言資料庫進行判斷;

3.報告優化;