一、环境准备
1、TestNG安装
参考博客:https://blog.csdn.net/weixin_43184774/article/details/96164366
2、IntelliJ IDEA安装
参考博客:https://blog.csdn.net/weixin_43184774/article/details/100577723
3、Postman安装
参考博客:https://blog.csdn.net/weixin_43184774/article/details/10057855
4、JDK安装
参考博客:https://blog.csdn.net/weixin_43184774/article/details/96164366
二、postman请求测试(GET和POST请求)
1、测试用户登录接口:POST请求(带Headers和Body参数)
请求地址:http://192.168.2.99:28013/api/platform/user/login
Headers的KEY:'Content-Type ' VALUE:'application/json'
Body参数:
{
"username": "admin",
"password": "123456"
}
封装token值:(将这个token值封装起来,因为登录的token值,后面很多地方都要依赖这个token值)
(1)先调通登录接口,并获得服务器返回的Response Body的token值
(2) 查看登录接口的Tests值:点击“Set an environment variable”
默认值为:'pm.environment.set("variable_key","variable_value");'
(3)修改Test默认值为:'pm.environment.set("token", pm.response.json().data.token);',这样后面就可以动态获取这个token值了
封装请求url地址:(因为url地址每次输入一大串IP,比较麻烦,可以将其封装起来)
(1)点击Postman页面中的眼睛图标
(2)点击"Edit"
(3)填入变量名和值,变量名随便输入,这个值就是你要封装的url地址,比如这里的http://192.168.2.99:28013/api/platform
(4)修改登录接口的请求地址为:{{user_login}}/user/login
2、测试用户退出接口:POST请求(带Headers:依赖登录的token值)
请求地址:http://192.168.2.99:28013/api/platform/user/logout
Headers的KEY:'Authorization ' VALUE:'{{token}}'
3、测试用户检查接口:GET请求(带Headers:依赖登录的token值,带Params参数)
请求地址:http://192.168.2.99:28013/api/platform//user/check
Headers的KEY:'Authorization ' VALUE:'{{token}}'
Params的KEY:'username ' VALUE:'admin'
三、JAVA代码+TestNG框架实现Postman的各种请求
1、打开IntelliJ IDEA,新建maven工程:Api_Autotest
(1)File——>New——>Project
(2)选择Maven,选择Project SDK,我这里安装的JDK环境是JDK1.8,点击“Next”
(3)输入工程名:Api_Autotest,点击“Next”
(4)输入项目工程名,选择保存路径,点击“Finish”
(5)查看新建完成的工程目录
2、导入pom文件,项目工程要依赖的包文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Api_Autotest</groupId>
<artifactId>Api_Autotest</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.11</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.59</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.linkedin.pegasus</groupId>
<artifactId>test-util</artifactId>
<version>1.15.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.relevantcodes/extentreports -->
<dependency>
<groupId>com.relevantcodes</groupId>
<artifactId>extentreports</artifactId>
<version>2.41.0</version>
</dependency>
<dependency>
<groupId>com.vimalselvam</groupId>
<artifactId>testng-extentsreport</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.3.0</version>
</dependency>
<!--引入extentreports相关包-->
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.1.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>2.12.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
<compilerArgs>
<arg>-Xlint:unchecked</arg>
<arg>-Xlint:deprecation </arg>
<!--<arg>endorseddirs=${endorsed.dir}</arg>-->
</compilerArgs>
</configuration>
</plugin>
<!-- 添加插件 关联testNg.xml-->
<plugin>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-surefire-plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
<suiteXmlFiles>
<!--suppress UnresolvedMavenProperty -->
<suiteXmlFile>${xmlFileName}</suiteXmlFile>
</suiteXmlFiles>
<workingDirectory>target/</workingDirectory>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
</properties>
</project>
3、方法封装
(1)在src/main/java下新建一个包:选中java右键选择New——>Package,输入包名:com.methodpackage
(2)在com.methodpackage目录下再相继新建几个新包,如下所示:
(3)在com.methodpackage.basic包下,新建一个java类:testbasic,输入如下代码。(这个类文件用于封装请求的断言。后面如果还想封装其它方法之类的,也可以直接放在这个类中,直接调用就可以了)
package com.methodpackage.basic;
import java.util.Properties;
public class testbasic {
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;
}
(4)在com.methodpackage.restclient包下,新建一个java类:restclient,输入如下代码。(这个类用于封装Get请求方法)
package com.methodpackage.restclient;
import java.io.IOException;
import com.methodpackage.basic.testbasic;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
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 org.apache.http.Header;
import org.testng.Assert;
import java.util.HashMap;
public class restclient extends testbasic {
// Get请求
public CloseableHttpResponse get(String url) throws ClientProtocolException, IOException {
// 创建一个可关闭的HttpClient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建一个HttpGet的请求对象
HttpGet httpget = new HttpGet(url);
// 执行请求,相当于postman上点击发送按钮,然后赋值给HttpResponse对象接收
CloseableHttpResponse httpResponse = httpclient.execute(httpget);
// 设置超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(2000)
.setConnectionRequestTimeout(2000)
.build();
httpget.setConfig(requestConfig);
// 添加断言,获取服务器响应的状态码
int statusCode = httpResponse.getStatusLine().getStatusCode();
Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "服务器返回的状态码不是200");
System.out.println("服务器响应的状态码为:" + statusCode);
// 获取响应头信息,返回是一个数组
Header[] headerArray = httpResponse.getAllHeaders();
// 创建一个hashmap对象,通过postman可以看到请求响应头信息都是Key和value得形式
HashMap<String, String> hm = new HashMap<String, String>();
// 增强for循环遍历headerArray数组,依次把元素添加到hashmap集合
for(Header header : headerArray) {
hm.put(header.getName(), header.getValue());
}
// 打印hashmap
System.out.println("Response Headers的结果为:"+ hm);
// 关闭
return httpResponse;
}
}
(5)在com.methodpackage.util包下,新建一个java类:util_json,代码如下。(这个类用于封装接口请求的断言)
package com.methodpackage.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class util_json {
/**
*
* @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对象名称对应的值
*/
//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();
}
}
4、代码实现
登录接口测试:
(1)在com路径下,新建一个包:testcase,用于存放测试用例
(2)在testcase包路径下,新建一个类,类名叫login,输入如下代码。(这个类用于验证之前Postman的登录接口)
package com.testcase;
import com.alibaba.fastjson.JSON;
import com.methodpackage.basic.testbasic;
import org.apache.http.Header;
import org.apache.http.client.config.RequestConfig;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
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 org.apache.http.util.EntityUtils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
/**
* @author Anker
* @date 2019/08/22
* @analysis login用例是登录接口——>(POST请求:带Body参数,不带Params参数,不带Headers参数,application/json格式)
*/
public class login extends testbasic {
public String token; //定义一个变量,用于存放登录后的token值
// 登录接口测试并获取token值
@Test
public void Login_POST_APITest() throws Exception {
// 通过HttpPost来发送post请求,带Body参数
HttpPost httpPost = new HttpPost("http://192.168.2.99:28013/api/platform/user/login");
JSONObject jsonParam = new JSONObject();
jsonParam.put("username", "admin");
jsonParam.put("password", "123456");
StringEntity entity = new StringEntity(jsonParam.toString(),"utf-8");
entity.setContentEncoding("UTF-8");
// Headers的Content-Type类型
entity.setContentType("application/json");
httpPost.setEntity(entity);
// 通过HttpClient来执行请求,获取一个响应结果
CloseableHttpClient httpClient = HttpClients.createDefault();
// 添加断言,获取服务器响应的状态码
CloseableHttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "服务器返回的状态码不是200");
System.out.println("服务器响应的状态码为:" + statusCode);
// 设置超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(2000)
.setConnectionRequestTimeout(2000)
.build();
httpPost.setConfig(requestConfig);
// 获取Response Headers的值
Header[] headerArray = response.getAllHeaders(); //获取响应头信息,返回是一个数组
HashMap<String, String> hm = new HashMap<String, String>(); //创建一个hashmap对象
// 增强for循环遍历headerArray数组,依次把元素添加到hashmap集合
for(Header header : headerArray) {
hm.put(header.getName(), header.getValue());
}
// 打印hashmap
System.out.println("Response Headers的结果为:"+ hm);
// 获取Content-Type的类型
HttpEntity httpentity = response.getEntity();
// 获取Response Body结果
String str = EntityUtils.toString(httpentity, "utf-8");
writeTxt(str.toString()); //调用writeTxt()函数,将Response Body的结果保存到本地文本文件中
System.out.println("登录接口的Response Body结果为:" + str);
// 登录成功后,获取服务器返回Body值里的token值
JSONObject json1 = JSON.parseObject(str); //将str的结果转换成json格式
String data = json1.getString("data");
JSONObject json2 = JSON.parseObject(data); //将data的结果转换成json格式
token = json2.getString("token");
System.out.println("登录成功后的token值为:" + token);
// 关闭
response.close();
}
// 将服务器的响应结果保存到本地文本文件中
public static void writeTxt(String str) throws Exception{
File file=new File("./Api_AutoTestCase");
if(!file.exists()){ //如果文件夹不存在
file.mkdir(); //创建文件夹
}
FileWriter fw = null;
String path = "./Api_AutoTestCase/登录接口的Response Body值.txt";
File f = new File(path);
try {
if (!f.exists()) {
f.createNewFile();
}
fw = new FileWriter(f);
BufferedWriter out = new BufferedWriter(fw);
out.write(str.toString());
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)选中login类文件,右键选择“Run login”,运行该登录接口的测试用例
(4)查看运行结果
(5)将代码实现的结果和Postman实现的结果进行对比,结果一样,则大功告成!
退出接口测试:
(1)在testcase包路径下,新建一个类,类名叫logout,输入如下代码。(这个类用于验证之前Postman的退出接口)
package com.testcase;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
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 org.apache.http.util.EntityUtils;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
/**
* @author Anker
* @date 2019/08/22
* @analysis logout用例是系统平台登出接口——>(POST请求:不带Body参数,不带Params参数,
* 带Headers参数(依赖登录接口),application/json格式)
*/
// 该类继承于登录接口的类
public class logout extends login {
@Test
public void Logout_POST_APITest() throws Exception {
Login_POST_APITest(); //调用系统平台登录接口
// 通过HttpPost来发送post请求
HttpPost httpPost = new HttpPost("http://192.168.2.99:28013/api/platform/user/logout");
httpPost.addHeader("Authorization", token); //带Headers参数(依赖系统平台登录接口)
JSONObject par = new JSONObject();
StringEntity entity = new StringEntity(par.toString(),"utf-8"); //解决中文乱码问题
entity.setContentEncoding("UTF-8");
// Headers的Content-Type类型
entity.setContentType("application/json");
httpPost.setEntity(entity);
// 通过HttpClient来执行请求,获取一个响应结果
CloseableHttpClient httpClient = HttpClients.createDefault();
// 添加断言,获取服务器响应的状态码
CloseableHttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "服务器返回的状态码不是200");
System.out.println("服务器响应的状态码为:" + statusCode);
// 设置超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(2000)
.setConnectionRequestTimeout(2000)
.build();
httpPost.setConfig(requestConfig);
// 获取Response Headers的值
Header[] headerArray = response.getAllHeaders(); //获取响应头信息,返回是一个数组
HashMap<String, String> hm = new HashMap<String, String>(); //创建一个hashmap对象
// 增强for循环遍历headerArray数组,依次把元素添加到hashmap集合
for(Header header : headerArray) {
hm.put(header.getName(), header.getValue());
}
// 打印hashmap
System.out.println("Response Headers的结果为:"+ hm);
// 获取Content-Type的类型
HttpEntity httpentity = response.getEntity();
// 获取Response Body结果
String str = EntityUtils.toString(httpentity, "utf-8");
writeTxt(str.toString()); //调用writeTxt()函数,将服务器响应的结果保存到本地文本文件中
System.out.println("退出接口的Response Body结果为:" + str);
// 关闭
response.close();
}
// 将服务器的响应结果保存到本地文本文件中
public static void writeTxt(String str) throws Exception{
File file=new File("./Api_AutoTestCase");
if(!file.exists()){ //如果文件夹不存在
file.mkdir(); //创建文件夹
}
FileWriter fw = null;
String path = "./Api_AutoTestCase/退出接口的Response Body值.txt";
File f = new File(path);
try {
if (!f.exists()) {
f.createNewFile();
}
fw = new FileWriter(f);
BufferedWriter out = new BufferedWriter(fw);
out.write(str.toString());
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(2)选中logout类文件,右键选择“Run logout”,运行该退出接口的测试用例
(3)查看运行结果
(4)将代码实现的结果和Postman实现的结果进行对比,结果一样,则大功告成!