rest-assured接口自动化框架

接口请求方法

常见接口请求方法构造

  • when().get(URL) 构造 HTTP 协议中的 GET 请求。
  • when().post(URL) 构造 HTTP 协议中的 POST 请求。
  • when().put(URL) 构造 HTTP 协议中的 PUT 请求。
  • when().delete(URL) 构造 HTTP 协议中的 DELETE 请求。

RESTAssured的基本使用

  • 准备数据:given()
  • 发送请求:when()
  • 验证返回结果:then()

接口请求参数

get 请求参数传递方式

  • 方式一:直接拼接在 URL 中:
    • ?username=Hogwarts&id=666
  • 方式二:通过given()的queryParam()传递:
    • given(): 表示发起请求之前的数据准备
    • queryParam():单个URL参数
    • queryParams():多个URL参数。

接口请求头

  • HTTP 请求头是在 HTTP 请求消息中包含的元数据信息,用于描述请求或响应的一些属性和特征。
  • 实际工作过程中具体要关注的头信息字段需要和研发沟通。
  • 常见的头信息(右侧表格):
    • Authorization: 表示客户端请求的身份验证信息
    • Cookie: 表示客户端的状态信息,通常用于身份验证和会话管理
    • Content-Type: 表示请求消息体的 MIME 类型
    • User-Agent: 发送请求的客户端软件信息
    • 其他: 根据接口文档设计要求决定其作用

Headers

  • 简介
    • HTTP Headers 也叫做 HTTP 消息头
    • 允许客户端和服务器传递附加信息
    • 由名称、冒号、具体的值组成
  • 设置请求 Headers
    • .header(): 添加单个 header 键值对,且支持多个值
    • .headers(): 添加多个 header 键值对
  • 示例源码
package com.vernon.headers_cookie;

import com.alibaba.fastjson2.JSONObject;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static io.restassured.specification.ProxySpecification.host;

public class TestHeadersCookie {

    @Test
    public void testHeaders() {

        // 配置添加代理,方便 Charles 监听 请求和响应
        RestAssured.proxy=host("127.0.0.1").withPort(8888);
        // 忽略 HTTPS 校验
        RestAssured.useRelaxedHTTPSValidation();

        JSONObject headers = new JSONObject(){{
            put("header1", "value1");
            put("header2","value2");
        }};
        given()
                // 添加单个 header 键值对,且支持多个值
                .header("User-Agent", "Mozilla","Chrome")
                // 添加多个 header 键值对
                .headers(headers)
        .when()
                .get("https://httpbin.ceshiren.com/get")
        .then()
                .statusCode(200);

    }
}

Cookie

  • 设置 Cookie 的两种方式
    • 通过header()/headers()添加
    • 通过.cookie() / .cookies() 方法添加
    • 添加cookie不能同时使用header 和cookie,同时存在时,通过cookie方法会覆盖header方法
  • 示例源码
package com.vernon.headers_cookie;

import com.alibaba.fastjson2.JSONObject;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static io.restassured.specification.ProxySpecification.host;

public class TestHeadersCookie {

    @Test
    public void testCookies() {
        // 配置添加代理,方便 Charles 监听 请求和响应
        RestAssured.proxy=host("127.0.0.1").withPort(8888);
        // 忽略 HTTPS 校验
        RestAssured.useRelaxedHTTPSValidation();

        given()
                // 通过header/headers 添加 Cookie
                .header("Cookie", "my_cookie1=value1")
                // 通过cookie 添加 单个cookie信息
                .cookie("my_cookie2","value2")
                // 通过 cookies 添加多个 cookie信息
                .cookies("1_cookie","1_value","2_cookie","2_value")
        .when()
                .get("https://httpbin.ceshiren.com/get")
        .then()
                .statusCode(200);
    }
}

常用接口请求体应用场景

  • JSON(JavaScript Object Notation)

    • 轻量级的数据交换格式,最常见的一种类型。
    • Content-Type = application/json
  • 表单数据(Form Data)

    • 以键值对的形式提交数据,例如通过 HTML 表单提交数据。
    • Content-Type = application/x-www-form-urlencoded
  • XML(eXtensible Markup Language)

    • 常用的标记语言,
    • 通常用于传递配置文件等数据。
    • Content-Type = application/xml
    • Content-Type = text/xml
  • 文件(File)

    • 可以通过请求体上传文件数据,例如上传图片、视频等文件。
    • 上传文件的 MIME 类型
      • Content-Type = image/jpeg
      • Content-Type = multipart/form-data
  • 纯文本(Text)

    • 纯文本数据,例如发送邮件、发送短信等场景
    • Content-Type = text/plain
  • 其他格式

    • 二进制数据、protobuf 等格式

接口请求体-json

JSON 类型接口请求体构造

  • 通过given().body(jsonData)添加请求体信息:
    • JSON 对象 。
    • 直接复制 String 。
  • JSONOject对象解析依赖
<!-- 阿里开源JSON解析包 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.52</version>
</dependency>
  • 示例源码
package com.vernon.body.json;

import com.alibaba.fastjson2.JSONObject;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;

public class TestJson {
    
    @Test
    void objectPostJson(){
        // 直接构造一个 JSON 对象,适用于格式不复杂的场景
        JSONObject requestBody = new JSONObject();
        requestBody.put("key1", "value1");
        requestBody.put("key2", "value2");
        given()
            // body()方法传递 JSON 请求体,类型为 String 
            .body(requestBody.toString()).log().all()
        .when()
            .post("https://httpbin.ceshiren.com/post")
        // 打印全部的相应信息
            .then().log().all();
    }
        
    @Test
    void stringPostJson(){
        // 从现有的请求信息中 copy 的请求体
        String jsonData = "{\"username\":\"hogwarts\",\"password\":\"test12345\",\"code\":\"\"}";
        given()
                .body(jsonData).log().all()
                .when()
                .post("https://litemall.hogwarts.ceshiren.com/admin/auth/login")
                // 打印全部的相应信息
                .then().log().all();

    }
}

接口请求体-文件

  • Content-Type 类型: multipart/form-data
  • REST-assured 上传文件
    • 创建本地文件: hogwarts.txt
    • 调用方法: multiPart()
      • 参数:String name
      • 参数:File file
  • 示例源码
package com.vernon.multipart;

import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;

import java.io.File;

import static io.restassured.RestAssured.given;
import static io.restassured.specification.ProxySpecification.host;

public class TestMultipart {
    @Test
    void testMultipart(){

        // 需要上传的文件对象
        File file = new File("src/test/resources/hogwarts.txt");

        // 定义本地代理配置
        RestAssured.proxy = host("127.0.0.1").withPort(7897);
        // 忽略 HTTPS 证书校验
        RestAssured.useRelaxedHTTPSValidation();

        given()
            .log().all()
            .contentType("multipart/form-data")
            // 传递文件对象
            .multiPart("hogwarts", file)
            // 传递JSON数据
            .multiPart("ceshiren","{\"hogwarts\",6666}","application/json")
        .when()
            .post("https://httpbin.ceshiren.com/post")
        .then()
            .log().all()
            .statusCode(200);

    }
}

接口请求体-form表单

  • Content-Type 类型: application/x-www-form-urlencoded
  • 应用场景
    • 数据量不大
    • 数据层级不深的情况
    • 通常以键值对传递
  • rest-assured 发送表单请求参数
    • 单个参数传递: 调用 formParam() 方法
    • 多个参数传递: 调用 formParams() 方法
  • 示例源码
package com.vernon.form;

import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;

import java.util.HashMap;

import static io.restassured.RestAssured.given;
import static io.restassured.specification.ProxySpecification.host;

public class TestForm {
    @Test
    public void testForm() {

        RestAssured.proxy=host("127.0.0.1").withPort(7897);
        RestAssured.useRelaxedHTTPSValidation();

        HashMap<String, Object> form = new HashMap<>(){{
            put("firstName", "John");
            put("lastName", "Doe");
        }};
        given()
                // 单个表单参数
                .formParam("myParam", "myValue")
                // 多个表单参数
                .formParams(form)
                .log().headers()
                .log().body()

        .when()
                .post("https://httpbin.ceshiren.com/post")
        .then()
                .log().all()
                .statusCode(200);
    }
}

接口请求体-xml

  • 示例接口地址:http://dneonline.com/calculator.asmx
  • xml文件读取解析IOUtils依赖
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
        <scope>test</scope>
    </dependency>
    
  • xml请求数据文件
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <Add xmlns="http://tempuri.org/">
            <intA>1</intA>
            <intB>1</intB>
        </Add>
    </Body>
</Envelope>
  • 示例源码
package com.vernon.xml;

import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import static io.restassured.RestAssured.given;

public class TestXml {
    @Test
    public void testXml() throws IOException {

        // 定义请求体数据:源自 XML 文件对象
        File file = new File("src/test/resources/add.xml");
        FileInputStream fis = new FileInputStream(file);
        String xmlStr = IOUtils.toString(fis, StandardCharsets.UTF_8);
        fis.close();
        given()
                // 定制请求内容媒体类型
                .contentType("text/xml; charset=utf-8")
                // 定制请求体数据
                .body(xmlStr)
                .log().all()
        .when()
                .post("http://dneonline.com//calculator.asmx")
        .then()
                .log().all()
                .statusCode(200);

    }
}

接口响应断言

断言的目的

  1. 验证响应状态码。
  2. 验证响应体返回字段信息是否符合业务需求。
  3. 验证响应体字段的数据类型、数据格式。

响应状态码简介

响应状态码是 响应报文里的code字段

# 响应报文
< HTTP/1.1 200 OK
< Server: nginx/1.10.2
< Date: Thu, 12 Mar 2020 09:13:44 GMT
< Content-Type: image/png
< Content-Length: 11390
< Connection: keep-alive

响应断言的方式

  • 状态码: then().statusCode()
  • 响应头: then().header()
  • 响应体: then().body()

响应状态码断言

  • then().statusCode()
  • 示例源码
package com.vernon.response.status;

import static io.restassured.RestAssured.given;
import org.junit.jupiter.api.Test;

public class TestAssertionStatusCode {
    @Test
    void testStatusCode(){
        given()
        .when()
                .get("https://httpbin.ceshiren.com/get")  // 发起GET请求
        .then()
                .log().all()  // 打印响应结果
                .statusCode(200);  // 响应状态码断言
    }

}

JSON响应体断言

  • 方法1: 直接断言: then().body()。
    • 结合 hamcrest 使用。
    • body(“想要提取的信息”, 预期结果操作)。
    • 使用 gpath 语法提取(了解)。
  • 方法2: 提取后断言: then().extract().path();
    • extract(): 提取方法,返回值为Response。
    • path(): 从返回值中提取想要的信息(使用 gpath 语法)。

xml响应断言

  • XPath 语法
/   根节点
.   现行节点
//  不管位置,选择所有符合条件的元素
*   匹配所有元素节点
[]  迭代器标示
|   支持迭代器中做多选
  • 示例代码
package com.vernon.xml;

import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;

public class TestAssertionXML {
    @Test
    public void testAssertionXML() throws IOException {
        // 定义请求体数据: 源自文件XML对象
        File file = new File("src/test/resources/add.xml");
        FileInputStream fis = new FileInputStream(file);
        String xmlBody = IOUtils.toString(fis, StandardCharsets.UTF_8);
        fis.close();
        given()
                .contentType("application/xml")
                .body(xmlBody)
        .when()
                .post("http://dneonline.com//calculator.asmx")

        .then()
                .statusCode(200)
                .body("//AddResult.text()",equalTo(2));
    }
}

多层嵌套响应断言

  • JSONPath 简介
    • 在 JSON 数据中定位和提取特定信息的查询语言。
    • JSONPath 使用类似于 XPath 的语法,使用路径表达式从 JSON 数据中选择和提取数据。
    • 相比于传统的提取方式,更加灵活,并且支持定制化。
  • JSONPath 语法
    • $. 查询的根节点对象,用于表示一个 json 数据,可以是数组或对象
    • @ 过滤器(filter predicate)处理的当前节点对象
    • * 通配符
    • . 获取子节点
    • .. 递归搜索,筛选所有符合条件的节点
    • ?() 过滤器表达式,筛选操作
    • [start:end] 数组片段,区间为[start,end),左闭右开
    • [A]或[A,B] 迭代器下标,表示一个或多个数组下标
  • JsonPath依赖
<!-- json path 解析json文件 -->
<properties>
    <json-path.version>2.8.0</json-path.version>
</properties>
<dependency>
      <groupId>com.jayway.jsonpath</groupId>
      <artifactId>json-path</artifactId>
      <version>${json-path.version}</version>
  </dependency>
  • 示例源码
public class TestJsonpath {
    @Test
    void jsonpathRes(){
        String jsonData = "{\"username\":\"hogwarts\",\"password\":\"test12345\",\"code\":\"\"}";
        String res = given()
                .body(jsonData)
                .when()
                .post("https://httpbin.hogwarts.ceshiren.com/post")
                .then()
                .extract().response().getBody().asString();
        // 第一种获取方式
        DocumentContext context = JsonPath.parse(res);
        ArrayList<String> codeList = context.read("$..code");
        // 第二种获取方式
        ArrayList<String> codeList2 = JsonPath.read(res, "$..code");
    }
}

整体结构响应断言

  • JSON Schema简介
    • 是使用 JSON 格式编写的
    • 可以用来定义校验 JSON 数据的结构
    • 可以用来校验 JSON 数据的一致性
    • 可以用来校验 API 接口请求和响应
  • 生成JSON Schema文档
    • 在线生成工具:https://app.quicktype.io
    • 复制 JSON 数据
    • 粘贴到在线生成工具中
    • 自动生成 JSON Schema 数据
  • JSON Schema 依赖配置
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>4.4.0</version>
    <scope>test</scope>
</dependency>
  • JSON Schema 响应断言

java语言示例

import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;

public class TestJsonSchema {

    @Test
    void func() {

        given()
                .header("Hello", "Hogwarts")
        .when()
                .get("https://httpbin.ceshiren.com/get")  // 发送请求
        .then()
                .log().all()  // 打印完整的响应信息
                .assertThat()
                .body(matchesJsonSchemaInClasspath("schema.json"));  // JSON Schema 断言
    }
}

python语言示例

import requests
from jsonschema import Draft7Validator, validates, RefResolver
 
# 定义Json Schema
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer", "minimum": 0}
    },
    "required": ["name", "age"]
}
 
# 获取API数据
response = requests.get('https://api.example.com/data')
 
# 确保请求成功
if response.status_code == 200:
    data = response.json()
    
    # 创建解决器和验证器
    resolver = RefResolver('file://', schema)
    validator = Draft7Validator(schema, resolver=resolver)
    
    # 验证数据
    if validator.is_valid(data):
        print("数据验证通过")
    else:
        print("数据验证失败")
        for error in validator.iter_errors(data):
            print(error.message)
else:
    print("请求API失败")

数据库操作与断言

数据库操作注意事项

  • 直接对数据库做查询之外的操作是非常危险的行为
  • 权限管理严格的公司数据库权限给的非常低
  • 表结构复杂,随便删除数据会影响测试,甚至会导致系统出现异常

数据库封装

创建一个工具类,输入SQL,返回查询结果

添加依赖

<!--        jdbc 的driver依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>
<!-- 数据库查询结果集转换成标准Json格式的工具 -->
<dependency>
    <groupId>org.jooq</groupId>
    <artifactId>jooq</artifactId>
    <version>3.11.11</version>
</dependency>
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.6.0</version>
    <scope>test</scope>
</dependency>
  • 代码示例
public class DatabaseUtils {
    Statement statement;
    Connection conn;
    // 初始化数据库信息
    public DatabaseUtils(String DB_URL, String USER, String PASS) {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
            
            // 问题: Operation not allowed for a result set of type ResultSet. TYPE_FORWARP_ONLY.
            // 解决方案: createStatement 添加配置 ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY
            statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    // 根据 sql 返回在单个字段数据库查询的信息
    public List<String> getResultStringListBySQL(String sql_query, String columnLabel){
        List<String> resList = new ArrayList<>();
        try {
            ResultSet resultSet = statement.executeQuery(sql_query);
            while (resultSet.next()){
            resList.add(resultSet.getString(columnLabel));
            }
        }catch (SQLException e) {
            e.printStackTrace();
        }
        return resList;
    }
    // 根据sql查询返回多个字段并转化为标准的json格式
    public String getResultSetBySQL(String sql_query) {
        // 格式转换将ResultSet 转换为 标准的json格式,方便断言时使用JsonPath获取对应信息。
        try {
            ResultSet resultSet = statement.executeQuery(sql_query);
            // 获取所有
            ResultSetMetaData md = resultSet.getMetaData();
            int numCols = md.getColumnCount();
            // 获取所有的数据表列名
            List<String> colNames = new ArrayList<>();
            for (int i = 1; i <= numCols; i++) {
                String name = md.getColumnName(i);
                colNames.add(name);
            }
            // 返回一个json结构的查询结果
            return DSL.using(conn)
                    .fetch(resultSet)
                    .map(new RecordMapper() {
                        @Override
                        public JSONObject map(Record r) {
                            JSONObject obj = new JSONObject();
                            colNames.forEach(cn -> obj.put(cn, r.get(cn)));
                            return obj;
                        }
                    }).toString();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 如果异常,return 空 json,不影响后续逻辑执行
        return "{}";
    }
}

接口超时处理

  • 设置超时时间 步骤:
    • 第1步: 创建 HttpClientConfig 实例对象,并设置响应超时时长为3秒,单位是毫秒
      HttpClientConfig httpClientConfig = HttpClientConfig.httpClientConfig()
              .setParam("http.connection.timeout", 5000)
              .setParam("http.socket.timeout", 3000);
      
    • 第2步: 创建 RestAssuredConfig 实例对象,传入 HttpClientConfig 实例对象
      RestAssuredConfig restAssuredConfig = RestAssuredConfig.config()
              .httpClient(httpClientConfig);
      
    • 第3步: given 语句中调用 config() 方法,传入 RestAssuredConfig 实例对象设置超时处理时间为3秒
      given().config(restAssuredConfig)
      
  • 示例源码
package com.vernon.timeout;

import io.restassured.RestAssured;
import io.restassured.config.HttpClientConfig;
import io.restassured.config.RestAssuredConfig;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static io.restassured.specification.ProxySpecification.host;

public class TestTimeout {

    @BeforeAll
    static void setupClass() {
        RestAssured.baseURI = "https://httpbin.ceshiren.com";
        // 配置全局代理
        RestAssured.proxy = host("localhost").withPort(8888);
        // 忽略 HTTPS 校验
        RestAssured.useRelaxedHTTPSValidation();
    }
    @Test
    void testCase1(){
        given()
        .when()
                .get("/get")
        .then()
                .statusCode(200);

    }
    @Test
    void testCase2(){

        // 创建 HttpClientConfig 实例 并设置 超时时间为3秒
        HttpClientConfig httpClientConfig = HttpClientConfig
                .httpClientConfig()
                .setParam("http.connection.timeout", 5000)
                .setParam("http.socket.timeout", 3000);

        // 创建 RestAssuredConfig 实例 并传入 HttpClientConfig 实例对象
        RestAssuredConfig restAssuredConfig = RestAssuredConfig
                .config()
                .httpClient(httpClientConfig);

        given()
                // 传入 RestAssuredConfig 实例 设置超时时间为3秒
                .config(restAssuredConfig)
                // 配置局部代理
                .proxy("localhost", 8888)
                // 忽略 HTTPS 校验
                .relaxedHTTPSValidation()
                .log().all()
        .when()
                .get("/delay/10")
        .then()
                .statusCode(200);

    }
    @Test
    void testCase3(){

        given()
        .when()
                .get("/get")
        .then()
                .statusCode(200);


    }
}

接口鉴权的多种情况与解决方案

  • 接口鉴权就是: 身份认证

后端接口鉴权常用方法

1729697091425

cookie 鉴权

  • cookie 的获取(根据接口文档获取)
  • 发送携带 cookie 的请求
    • 直接通过调用 cookie 方法
    • 通过在 filter 中添加 cookieFilter 对象
  • 示例源码
import io.restassured.filter.cookie.CookieFilter;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;

// Cookie鉴权
public class AddCookieByFilter {

    // 问题:通常 cookie 是不能像用户名密码一样有直接的数据的。
    // 解决方案: 模拟正常的set-cookie的过程

    @Test
    void addCookieByFilter(){

        CookieFilter cookieFilter = new CookieFilter();
        // 第一次请求: 客户端向服务端发起 set-cookie 的请求操作
        // -> https://httpbin.ceshiren.com/cookies/set/user/ad
        // <- set-cookie
        // -> redirect https://httpbin.ceshiren.com/cookies

        given()
                .redirects().follow(false).filter(cookieFilter)
        .when()
                .get("https://httpbin.ceshiren.com/cookies/set/user/ad")
        .then()
                .log().all();

        // 问题: 如何在收到 set-cookie 后,将对应的 cookie 信息提取出来,并添加在下一次请求的 cookie 中。
        // 解决方案: 使用 cookieFilter
        // 第二次请求, 添加 cookie

        given()
                .filter(cookieFilter)
        .when()
                .get("https://httpbin.ceshiren.com/cookies")
        .then()
                .log().all();

        // 第三次请求添加新的 cookie 字段值
        given()
                .filter(cookieFilter).cookie("counts","2")
        .when()
                .get("https://httpbin.ceshiren.com/cookies")
        .then()
                .log().all();
    }
}

token 鉴权

  • token 的获取(根据接口文档获取)
  • 发送携带 token 的请求(根据接口文档获取)
  • 示例源码
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;

// token鉴权
public class AddToken {
 //
    @Test
    void addToken() {
        // token 的获取方法
        String body = "{\"username\":\"admin123\",\"password\":\"admin123\",\"code\":\"\"}";
        String token=given()
                .contentType(ContentType.JSON)
                .body(body)
        .when()
                .post("https://litemall.hogwarts.ceshiren.com/admin/auth/login")
        .then()
                .log().all()
                .extract().path("data.token");

        // 添加 token 以解决接口鉴权问题
        // 强调: token 的认证过程,尽量与研发确认
        given()
                .header("X-Litemall-Admin-Token", token)
        .when()
                .get("https://litemall.hogwarts.ceshiren.com/admin/goods/list")
        .then()
                .log().all();

    }
}

auth 鉴权

  • 在基本 HTTP 身份验证中,请求包含格式为 的标头字段Authorization: Basic
  • 其中credentials是 ID 和密码的Base64编码,由单个冒号连接:。
  • 示例源码
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;

// auth 鉴权
public class AddAuth {

    @Test
    void addAuth() {
        given()
                .auth().preemptive().basic("user", "ad")
        .when()
                .get("https://httpbin.ceshiren.com/basic-auth/user/ad")
        .then()
                .log().all();
    }
}

代理配置

代理简介

  • 介于客户端与服务器之间
  • 可以监听请求和响应信息
  • 充当防火墙和 Web 过滤器

代理与接口测试

  • 更直观的排查请求错误
    • 获取正确的的接口请求与响应信息
    • 开启代理工具监听请求
    • 获取自动化测试的请求与响应信息
    • 对比两次请求响应的区别

REST assured 使用代理

  • 开启代理工具监听请求
  • 配置代理
    • 局部:通过 proxy() 方法; 代理 HTTPS 请求,使用 useRelaxedHTTPSValidation() 忽略 HTTPS 证书验证
    • 全局:定义 proxy 对象; 代理 HTTPS 请求,使用 relaxedHTTPSValidation() 忽略 HTTPS 证书验证
    • 超时处理同时使用时,必须配置局部代理
  • 示例源码: 见超时代理

执行测试并生成allure报告

  • mvn clean test -Dtest=com.vernon.petstore.QueryTest allure:report
  • mvn allure:serve