先看看項目目錄:
一:第一步先創建一個maven項目,其中pom文件的的依賴如下
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.9</version>
</dependency>
</dependencies>
二:可以看到我們還有一個properties的配置文件,該文件目前就一個host,以後的各種key-value形式的數據都可以用配置文件進行維護(當然用數據庫存儲或者excel表格也是可以的,這裏不涉及)
三:然後我們來寫一個基礎類用來讀取配置文件中的key,定義的狀態碼是爲了以後做斷言用的,你也可以先不寫這個,直接註釋掉也是可以的
package com.yufeng.httpclient.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;
//寫一個構造函數
public TestBase() {
try {
prop = new Properties();
FileInputStream fis = new FileInputStream(".\\config.properties");
prop.load(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
四:讀取完配置文件後,我們就應該來創建client對象,get/post對象和httpresponse對象(client-->看做postman),用來發送請求的對象,我們將get和post請求都封裝到一個類中(老版本創建httpclient對象的時候,用的是
HttpClient httpClient = new DefaultHttpClient();
,但是這個方法已經差不多被棄用了,所以我們不用這個,我們用下面的方式)
package com.yufeng.httpclient.restclient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
import java.util.HashMap;
public class RestClient {
//1. Get 請求方法
public CloseableHttpResponse get(String url) throws IOException {
//創建一個可關閉的HttpClient對象
CloseableHttpClient httpclient = HttpClients.createDefault();
//創建一個HttpGet的請求對象
HttpGet httpget = new HttpGet(url);
//執行請求,相當於postman上點擊發送按鈕,然後賦值給HttpResponse對象接收
CloseableHttpResponse httpResponse = httpclient.execute(httpget);
return httpResponse;
}
// 2.POST請求方法
public CloseableHttpResponse post(String url, HashMap<String, String> headermap, String entityString) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
//加載請求頭到httppost對象
for (HashMap.Entry<String, String> entry : headermap.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
}
// 設置playload
httpPost.setEntity(new StringEntity(entityString));
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
return httpResponse;
}
}
五:接下來如果我們只做get請求,那就在來一個測試類就行了(如果需要做響應斷言,就自己寫一個util類進行解析,後續會將該類的方法提供出來)
package com.yufeng.httpclient;
import com.yufeng.httpclient.base.TestBase;
import com.yufeng.httpclient.restclient.RestClient;
import org.apache.http.client.methods.CloseableHttpResponse;
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 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");
}
}
這樣一個get請求的接口就差不多了,我們來看看結果:
然後我們來試試POST請求,一般post請求的入參我們都寫在一個JavaBean中,如下:
package com.yufeng.httpclient.bean;
public class UserInfo {
private String email;
private String password;
public UserInfo(String email, String password) {
super();
this.email = email;
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
因爲想到post返回的是json格式的,我們上面說了要寫一個util類進行解析,如下(這段代碼是copy別的大神的,直接拿來用就好了):
package com.yufeng.httpclient.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對象名稱對應的值
*/
//1 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();
}
}
然後我們去試一試這個post請求的情況:
package com.yufeng.httpclient;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yufeng.httpclient.base.TestBase;
import com.yufeng.httpclient.bean.UserInfo;
import com.yufeng.httpclient.restclient.RestClient;
import com.yufeng.httpclient.util.TestUtil;
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;
import java.util.HashMap;
public class PostApiTest 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/login";
System.out.println("接口地址:"+ url);
}
@Test
public void postapitest() throws IOException {
restClient = new RestClient();
//2.準備請求頭信息
HashMap<String, String> headermap = new HashMap<String, String>();
headermap.put("content-type", "application/json");
//3.對象轉換成Json字符串
UserInfo userInfo = new UserInfo("peter@klaven", "cityslicka");
String userJsonstring = JSON.toJSONString(userInfo);
System.out.println("請求數據:"+userJsonstring);
closeableHttpResponse = restClient.post(url, headermap, userJsonstring);
//驗證狀態碼是不是200
int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "status code is not 200");
//斷言響應json內容中token是不是期待結果
String responseString = EntityUtils.toString(closeableHttpResponse.getEntity());
JSONObject responseJson = JSON.parseObject(responseString);
System.out.println("響應數據:"+responseJson);
//System.out.println(responseString);
String token = TestUtil.getValueByJPath(responseJson, "token");
Assert.assertEquals(token, "QpwL5tke4Pnpja7X", "登錄失敗");
}
}
這是post請求的執行代碼,我們來看看結果:
請求成功!!!現在先記錄一下使用Testng+HttpClient進行接口測試的方式,後續再加上log4j和Extentreports進行日誌的打印和報告的優化~~
項目下載地址:https://pan.baidu.com/s/1GRVf0g4vRuEAvigyed4Jcg 提取碼:573g