java介面自動化2——get方法重構和json解析
我們介紹了Get方法的設計過程和測試結果,現在我們需要對前面程式碼進行重構和修改,本篇主要的工作如下 :
1)重構Get方法
2)如何進行JSON解析
3)使用TestNG方法進行測試斷言
1、重構Get方法
前面一篇寫的Get方法比較繁瑣,不光寫了如何進行Get請求,還寫了獲取http響應狀態碼和JSON轉換。現在我們需要抽取出來,設計Get請求方法,就只幹一件事情,那就是如何傳送get請求,其他的不要管。
我們知道,請求之後會返回一個HTTP的響應物件,所以,我們把get方法的返回值型別改成了響應物件,並帶上返回語句,重構程式碼之後,get方法程式碼如下。
package com.qa.restclient; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import java.io.IOException; public class RestClient { //重構後Get方法: public CloseableHttpResponse get(String url) throws ClientProtocolException,IOException{ //建立一個可關閉的HttpClient物件 CloseableHttpClient httpclient=HttpClients.createDefault(); //建立一個HttpGet的請求物件 HttpGet httpget=new HttpGet(url); //執行請求,相當於jmeter上點選執行按鈕,然後賦值給HttpResponse物件接收 CloseableHttpResponse httpResponse=httpclient.execute(httpget); return httpResponse; } }
由於我們不想在程式碼裡寫死例如像HTTP響應狀態碼200這樣的硬編碼,所以,這裡我們在TestBase.java裡把狀態碼給用常量寫出來,方便每一個TestNG測試用例去呼叫去斷言,TestBase中的程式碼修改後如下:
package com.qa.base; import org.testng.TestException; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; public class TestBase { public Properties prop; public int RESPONSE_STATUS_CODE_200=200; public int RESPONSE_STATUS_CODE_201=201; public int RESPONSE_STATUS_CODE_404=404; public int RESPONSE_STATUS_CODE_500=500; public TestBase(){ try{ prop=new Properties(); FileInputStream fis=new FileInputStream(System.getProperty("user.dir")+"/src/main/java/com/qa/config/config.properties"); prop.load(fis); }catch(FileNotFoundException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } } //mian函式主要是為了檢測user.dir目錄是否正確,執行結果:E:\Java_project\MavenProject_script正是當前專案的目錄 public static void main(String[] args){ System.out.println(System.getProperty("user.dir")); } }
現在我們的測試類程式碼修改之後如下
package com.qa.tests;
import java.io.IOException;
importorg.apache.http.client.ClientProtocolException;
importorg.apache.http.client.methods.CloseableHttpResponse;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.qa.base.TestBase;
import com.qa.restclient.RestClient;
public class GetApiTest extends TestBase{
TestBase testBase;
String host;
String url;
RestClient restClient;
CloseableHttpResponse closeableHttpResponse;
@BeforeClass
public void setUp() {
testBase = new TestBase();
host = prop.getProperty("HOST");
url = host + "/api/users";
}
@Test
public void getAPITest() throws ClientProtocolException, IOException {
restClient = new RestClient();
closeableHttpResponse= restClient.get(url);
//斷言狀態碼是不是200
int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
Assert.assertEquals(statusCode,RESPNSE_STATUS_CODE_200, "response status code is not 200");
}
}
2.寫一個JSON解析的工具類
在上面部分,我們只是寫了執行Get請求和狀態碼是否200的斷言。接下來,我們需要寫有一個JSON解析工具類,這樣就方便我們去json內容的斷言。
下面這個JSON資料截圖
上面是一個標準的json的響應內容截圖,第一個紅圈”per_page”是一個json物件,我們可以根據”per_page”來找到對應值是3,而第二個紅圈“data”是一個JSON陣列,而不是物件,不能直接去拿到裡面值,需要遍歷陣列。
下面,我們寫一個JSON解析的工具方法類,如果是像第一個紅圈的JSON物件,我們直接返回對應的值,如果是需要解析類似data數組裡面的json物件的值,這裡我們構造方法預設解析陣列第一個元素的內容。
在src/main/java下新建一個包:com.qa.util,然後在新包下建立一個TestUtil.java類。
TestUtil.java中的內容如下:
package com.qa.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class TestUtil {
/**
@param responseJson ,這個變數是拿到響應字串通過json轉換成json物件
* @param jpath,這個jpath指的是使用者想要查詢json物件的值的路徑寫法
* jpath寫法舉例:1) per_page 2)data[1]/first_name ,data是一個json陣列,[1]表示索引
* /first_name 表示data陣列下某一個元素下的json物件的名稱為first_name
* @return,返回first_name這個json物件名稱對應的值
*/
public static String getValueByJPath(JSONObject responseJson, String jpath){
Object obj=responseJson;
for(String s:jpath.split("/")){
if(!s.isEmpty()){
if(!(s.contains("[")||s.contains("]"))){
obj=((JSONObject) obj).get(s);
}else if(s.contains("[")||s.contains("]")){
obj=((JSONArray)((JSONObject)obj).get(s.split("\\[")[0])).get(Integer.parseInt(s.split("\\[")[1].replaceAll("]","")));
}
}
}
return obj.toString();
}
}
簡單解釋下上面的程式碼,主要是查詢兩種json物件的的值,第一種最簡單的,這個json物件在整個json串的第一層,例如上面截圖中的per_page,這個per_page就是通過jpath這個引數傳入,返回的結果就是3. 第二種jpath的查詢,例如我想查詢data下第一個使用者資訊裡面的first_name的值,這個時候jpath的寫法就是data[0]/first_name,查詢結果應該是Holt
3.TestNG測試用例
下面,我們TestNG測試用例程式碼如下:
package com.qa.tests;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qa.base.TestBase;
import com.qa.restclient.RestClient;
import com.qa.util.TestUtil;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.io.IOException;
public class GetApiTest extends TestBase {
TestBase testBase;
String host;
String url;
RestClient restClient;
CloseableHttpResponse closeableHttpResponse;
@BeforeClass
public void setUp(){
testBase =new TestBase();
host=prop.getProperty("HOST");
url=host+"/api/users";
}
@Test
public void getAPITest() throws ClientProtocolException, IOException {
restClient=new RestClient();
closeableHttpResponse=restClient.get(url);
int statusCode=closeableHttpResponse.getStatusLine().getStatusCode();
Assert.assertEquals(statusCode,RESPONSE_STATUS_CODE_200,"response status code is not200");
//把響應內容儲存在字串物件
String responseString= EntityUtils.toString(closeableHttpResponse.getEntity(),"UTF-8");
//建立Json物件,把上面字串序列化成Json物件
JSONObject responseJson= JSON.parseObject(responseString);
System.out.println("respon json from API-->" + responseJson);
//json內容解析
String s= TestUtil.getValueByJPath(responseJson,"data[1]/avatar");
System.out.println(s);
//Assert.assertEquals(“現實結果”, "期待結果","斷言失敗時候列印日誌訊息");
Assert.assertEquals(s,"Eve","first name is not Holt");
}
}
參考博文: