描述
在做接口自动化时,如果接口需要从登录接口中获取Cookie,并且把Cookie带入后面的接口请求头中进行后续的接口操作。如果不带入Cookie测试接口时会出现重定向301,比如在jmeter中会有自动重定向和跟随重定向一样。
jmeter跟随重定向与自动重定向区别
自动重定向:HttpClient接收到请求后,如果请求中包含重定向请求,HttpClient是可以自动跳转的,但是只针对GET和Head请求,勾选此项则“跟随重定向”失效;自动重定向可以自动转向到最终目标页面,但是JMeter是不记录重定向过程内容的,比如在查看结果树中是无法找到重定向过程内容的(A重定向到B,此时只记录B的内容不记录A的内容,A的响应内容我们暂时且叫过程内容),如果此时你想做关联,那就比较遗憾了,你无法关联到。
跟随重定向:Http Request取样器的默认选项,但响应Code是3XX时(比如301是重定向),自动跳转至目标地址。与自动重定向不同,JMeter会记录重定向过程中的所有请求响应,在查看结果树时可以看到服务器返回的内容,所以你可以对响应的内容做关联
比如你要测试登录,你把POST请求改为跟随重定向就可以了
案例
有两个接口,分别是登录接口和添加接口,添加接口需要从登录接口中获取Cookie并且放入请求头中才能请求成功。
使用框架Java+HttpClient+TestNg
public class Demo {
//保存获取的Cookie值
public Map<String, String> cookie = new HashMap<String, String>();
@Test
public void test_1() {
HttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost("接口地址");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "测试专员"));
params.add(new BasicNameValuePair("pwd", "123456789"));
try {
post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
HttpResponse report = httpClient.execute(post);
getAndStoreCookiesFromResponse(report);
if (report.getStatusLine().getStatusCode()== 200) {
String result = EntityUtils.toString(report.getEntity());
System.out.println(result);
} else {
System.out.println("请求失败");
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Test(dependsOnMethods = {"test_1"})
public void test_2() throws Exception {
HttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost("接口地址");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", "webApii"));
params.add(new BasicNameValuePair("yn", "1"));
params.add(new BasicNameValuePair("authScope", "3"));
params.add(new BasicNameValuePair("type", "1"));
params.add(new BasicNameValuePair("menuIds", "325,1011,1102,11024,11029"));
post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
addCookieInRequestHeaderBeforeRequest(post);
HttpResponse report = httpClient.execute(post);
if (report.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(report.getEntity());
System.out.println(result);
} else {
System.out.println("请求失败");
}
}
private void addCookieInRequestHeaderBeforeRequest(HttpPost post) {
String pinIdCookie = cookie.get("pin");
System.out.println(pinIdCookie);
if (pinIdCookie != null) {
post.setHeader("Cookie", pinIdCookie);
}
}
private void getAndStoreCookiesFromResponse(HttpResponse report) {
Header setCookieHeader = report.getFirstHeader("Set-Cookie");
if (setCookieHeader != null) {
String cookiePairsString = setCookieHeader.getValue();
System.out.println("Set-Cookie:" + cookiePairsString);
if (cookiePairsString != null && cookiePairsString.trim().length() > 0) {
String[] cookiePairs = cookiePairsString.split(";");
if (cookiePairs != null) {
for (String cookiePair : cookiePairs) {
if (cookiePair.contains("pin")) {
cookie.put("pin", cookiePair);
}
}
}
}
}
}
}
执行结果
代码详解
1. 登录接口
@Test
public void test_1() {
/*httpclients模拟https访问,下面示例通过HttpClients.createDefault()方式创建CloseableHttpClient对象实例(取代用new DefaultHttpClient()实例化) 解决了HTTPS安全证书认证问题。*/
HttpClient httpClient = HttpClients.createDefault();
//声明请求方式Post方式
HttpPost post = new HttpPost("接口地址");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "测试专员"));
params.add(new BasicNameValuePair("pwd", "123456789"));
try {
//将数据放入post请求中
post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
//执行post请求并且返回响应体
HttpResponse report = httpClient.execute(post);
//从响应体中获取响应报文中的Cookie
getAndStoreCookiesFromResponse(report);
//获取状态码,如果状态码为200,接口请求成功,并且获取响应数据
if (report.getStatusLine().getStatusCode()== 200) {
String result = EntityUtils.toString(report.getEntity());
System.out.println(result);
} else {
System.out.println("请求失败");
}
} catch (Exception e) {
e.printStackTrace();
}
}
2.保存Cookie
//保存获取的Cookie值
public Map<String, String> cookie = new HashMap<String, String>();
3.获取Cookie的方法
private void getAndStoreCookiesFromResponse(HttpResponse report) {
//从响应头中取出名字为"Set-Cookie"的响应头
Header setCookieHeader = report.getFirstHeader("Set-Cookie");
//如果取出的"Set-Cookie"不为空,取出响应头的值
if (setCookieHeader != null) {
String cookiePairsString = setCookieHeader.getValue();
System.out.println("Set-Cookie:" + cookiePairsString);
if (cookiePairsString != null && cookiePairsString.trim().length() > 0) {
//以";"分割
String[] cookiePairs = cookiePairsString.split(";");
if (cookiePairs != null) {
for (String cookiePair : cookiePairs) {
if (cookiePair.contains("pin")) {
//取出Cookie值保存到map集合中
cookie.put("pin", cookiePair);
}
}
}
}
}
}
4.添加接口
/*TestNG框架中的依赖,因为Cookie是从第一个登录接口中获取的,添加接口需要使用Cookie则需要依赖登录方法,只有登录方法执行完后获取cookie,添加方法才能获取到并且使用*/
@Test(dependsOnMethods = {"test_1"})
public void test_2() throws Exception {
HttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost("接口地址");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", "webApii"));
params.add(new BasicNameValuePair("yn", "1"));
params.add(new BasicNameValuePair("authScope", "3"));
params.add(new BasicNameValuePair("type", "1"));
params.add(new BasicNameValuePair("menuIds", "325,1011,1102,11024,11029"));
post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
//将获取到的Cookie设置到添加方法的Post请求中
addCookieInRequestHeaderBeforeRequest(post);
//执行Post请求
HttpResponse report = httpClient.execute(post);
if (report.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(report.getEntity());
System.out.println(result);
} else {
System.out.println("请求失败");
}
}
5.添加Cookie方法
private void addCookieInRequestHeaderBeforeRequest(HttpPost post) {
//根据Key获取Value
String pinIdCookie = cookie.get("pin");
System.out.println(pinIdCookie);
if (pinIdCookie != null) {
//将获取的Cookie放入Header中
post.setHeader("Cookie", pinIdCookie);
}
}