TestNG接口自动化封装用于模拟Postman的HTTP请求

一、环境准备

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实现的结果进行对比,结果一样,则大功告成!

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沧海黎明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值