在上篇文章,我們介紹了Get方法的設(shè)計(jì)過程和測(cè)試結(jié)果,現(xiàn)在我們需要對(duì)前面代碼進(jìn)行重構(gòu)和修改,本篇需要完成以下目標(biāo)。
10年積累的網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有尚義免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
1.重構(gòu)Get方法
在前面文章,說過,之前寫的Get方法比較繁瑣,不光寫了如何進(jìn)行Get請(qǐng)求,還寫了獲取http響應(yīng)狀態(tài)碼和JSON轉(zhuǎn)換?,F(xiàn)在我們需要抽取出來,設(shè)計(jì)Get請(qǐng)求方法,就只干一件事情,那就是如何發(fā)送get請(qǐng)求,其他的不要管。
我們知道,請(qǐng)求之后會(huì)返回一個(gè)HTTP的響應(yīng)對(duì)象,所以,我們把get方法的返回值類型改成了響應(yīng)對(duì)象,并帶上返回語句,重構(gòu)代碼之后,get方法代碼如下。
package com.qa.restclient; import java.io.IOException; 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; public class RestClient { //1. Get 請(qǐng)求方法 public CloseableHttpResponse get(String url) throwsClientProtocolException, IOException { //創(chuàng)建一個(gè)可關(guān)閉的HttpClient對(duì)象 CloseableHttpClienthttpclient = HttpClients.createDefault(); //創(chuàng)建一個(gè)HttpGet的請(qǐng)求對(duì)象 HttpGethttpget = newHttpGet(url); //執(zhí)行請(qǐng)求,相當(dāng)于postman上點(diǎn)擊發(fā)送按鈕,然后賦值給HttpResponse對(duì)象接收 CloseableHttpResponsehttpResponse = httpclient.execute(httpget); return httpResponse; } }
由于我們不想在代碼里寫死例如像HTTP響應(yīng)狀態(tài)碼200這樣的硬編碼,所以,這里我們?cè)赥estBase.java里把狀態(tài)碼給用常量寫出來,方便每一個(gè)TestNG測(cè)試用例去調(diào)用去斷言。
package com.qa.base; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; public class TestBase { public Properties prop; public int RESPNSE_STATUS_CODE_200 = 200; public int RESPNSE_STATUS_CODE_201 = 201; public int RESPNSE_STATUS_CODE_404 = 404; public int RESPNSE_STATUS_CODE_500 = 500; //寫一個(gè)構(gòu)造函數(shù) public TestBase() { try{ prop= new Properties(); FileInputStreamfis = 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(); } } }
現(xiàn)在我們的測(cè)試類代碼修改之后如下。
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); //斷言狀態(tài)碼是不是200 int statusCode = closeableHttpResponse.getStatusLine().getStatusCode(); Assert.assertEquals(statusCode,RESPNSE_STATUS_CODE_200, "response status code is not 200"); } }
測(cè)試運(yùn)行通過,沒毛病。
2.寫一個(gè)JSON解析的工具類
在上面部分,我們只是寫了執(zhí)行Get請(qǐng)求和狀態(tài)碼是否200的斷言。接下來,我們需要寫有一個(gè)JSON解析工具類,這樣就方便我們?nèi)son內(nèi)容的斷言。
下面這個(gè)JSON數(shù)據(jù)截圖
上面是一個(gè)標(biāo)準(zhǔn)的json的響應(yīng)內(nèi)容截圖,第一個(gè)紅圈”per_page”是一個(gè)json對(duì)象,我們可以根據(jù)”per_page”來找到對(duì)應(yīng)值是3,而第二個(gè)紅圈“data”是一個(gè)JSON數(shù)組,而不是對(duì)象,不能直接去拿到里面值,需要遍歷數(shù)組。
下面,我們寫一個(gè)JSON解析的工具方法類,如果是像第一個(gè)紅圈的JSON對(duì)象,我們直接返回對(duì)應(yīng)的值,如果是需要解析類似data數(shù)組里面的json對(duì)象的值,這里我們構(gòu)造方法默認(rèn)解析數(shù)組第一個(gè)元素的內(nèi)容。
在src/main/java下新建一個(gè)包:com.qa.util,然后在新包下創(chuàng)建一個(gè)TestUtil.java類。
package com.qa.util; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; public class TestUtil { /** * * @param responseJson ,這個(gè)變量是拿到響應(yīng)字符串通過json轉(zhuǎn)換成json對(duì)象 * @param jpath,這個(gè)jpath指的是用戶想要查詢json對(duì)象的值的路徑寫法 * jpath寫法舉例:1) per_page 2)data[1]/first_name ,data是一個(gè)json數(shù)組,[1]表示索引 * /first_name 表示data數(shù)組下某一個(gè)元素下的json對(duì)象的名稱為first_name * @return,返回first_name這個(gè)json對(duì)象名稱對(duì)應(yīng)的值 */ //1 json解析方法 public static String getValueByJPath(JSONObject responseJson, String jpath){ Objectobj = 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(); } }
簡(jiǎn)單解釋下上面的代碼,主要是查詢兩種json對(duì)象的的值,第一種最簡(jiǎn)單的,這個(gè)json對(duì)象在整個(gè)json串的第一層,例如上面截圖中的per_page,這個(gè)per_page就是通過jpath這個(gè)參數(shù)傳入,返回的結(jié)果就是3. 第二種jpath的查詢,例如我想查詢data下第一個(gè)用戶信息里面的first_name的值,這個(gè)時(shí)候jpath的寫法就是data[0]/first_name,查詢結(jié)果應(yīng)該是Eve。
3.TestNG測(cè)試用例
下面,我們TestNG測(cè)試用例代碼如下
package com.qa.tests; import java.io.IOException; 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 com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.base.TestBase; import com.qa.restclient.RestClient; import com.qa.util.TestUtil; 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?page=2"; } @Test public void getAPITest() throws ClientProtocolException, IOException { restClient = new RestClient(); closeableHttpResponse = restClient.get(url); //斷言狀態(tài)碼是不是200 int statusCode = closeableHttpResponse.getStatusLine().getStatusCode(); Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "response status code is not 200"); //把響應(yīng)內(nèi)容存儲(chǔ)在字符串對(duì)象 String responseString = EntityUtils.toString(closeableHttpResponse.getEntity(),"UTF-8"); //創(chuàng)建Json對(duì)象,把上面字符串序列化成Json對(duì)象 JSONObject responseJson = JSON.parseObject(responseString); //System.out.println("respon json from API-->" + responseJson); //json內(nèi)容解析 String s = TestUtil.getValueByJPath(responseJson,"data[0]/first_name"); System.out.println(s); } }
運(yùn)行測(cè)試結(jié)果:
[RemoteTestNG] detected TestNGversion 6.14.3 Eve PASSED: getAPITest
你還可以多寫幾個(gè)jpath來測(cè)試這個(gè)json解析工具類。
String s = TestUtil.getValueByJPath(responseJson,"data[1]/id"); String s = TestUtil.getValueByJPath(responseJson,"per_page");
4.TestNG自帶的測(cè)試斷言方法
這里簡(jiǎn)單提一下TestNG的斷言方法,我們一般測(cè)試都需要寫斷言的代碼,否則這樣的單元測(cè)試代碼就沒有意義。下面,我在statusCode和json解析的first_name進(jìn)行斷言。
package com.qa.tests; import java.io.IOException; 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 com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.base.TestBase; import com.qa.restclient.RestClient; import com.qa.util.TestUtil; 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?page=2"; } @Test public void getAPITest() throws ClientProtocolException, IOException { restClient = new RestClient(); closeableHttpResponse = restClient.get(url); //斷言狀態(tài)碼是不是200 int statusCode = closeableHttpResponse.getStatusLine().getStatusCode(); Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "response status code is not 200"); //把響應(yīng)內(nèi)容存儲(chǔ)在字符串對(duì)象 String responseString = EntityUtils.toString(closeableHttpResponse.getEntity(),"UTF-8"); //創(chuàng)建Json對(duì)象,把上面字符串序列化成Json對(duì)象 JSONObject responseJson = JSON.parseObject(responseString); //System.out.println("respon json from API-->" + responseJson); //json內(nèi)容解析 String s = TestUtil.getValueByJPath(responseJson,"data[0]/first_name"); System.out.println(s); Assert.assertEquals(s, "Eve","first name is not Eve"); } }
經(jīng)常使用的測(cè)試斷言:
Assert.assertEquals(“現(xiàn)實(shí)結(jié)果”, "期待結(jié)果","斷言失敗時(shí)候打印日志消息");
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。