接口自动化 - 了解接口自动化框架RESTAssured (Java版)

文章目录

  • [1. RESTAssure测试框架介绍-Java](#1. RESTAssure测试框架介绍-Java)
  • [2. RESTAssure测试框架使用](#2. RESTAssure测试框架使用)
    • [2.1 REST-assure环境准备:](#2.1 REST-assure环境准备:)
    • [2.2 REST-assure三剑客使用](#2.2 REST-assure三剑客使用)
      • [2.2.1 接口请求方式](#2.2.1 接口请求方式)
      • [2.2.2 REST-assure的接口请求方法](#2.2.2 REST-assure的接口请求方法)
      • [2.2.3 什么是请求参数构造](#2.2.3 什么是请求参数构造)
      • [2.2.4 如何发送携带参数的请求](#2.2.4 如何发送携带参数的请求)
      • [2.2.5 REST-assure方法使用](#2.2.5 REST-assure方法使用)
    • [2.3 接口请求头](#2.3 接口请求头)
      • [2.3.1 什么是请求头?](#2.3.1 什么是请求头?)
      • [2.3.2 请求头使用场景:](#2.3.2 请求头使用场景:)
      • [2.3.3 接口请求头构造方法:](#2.3.3 接口请求头构造方法:)
    • [2.4 接口请求体](#2.4 接口请求体)
      • [2.4.1 什么是接口请求体?](#2.4.1 什么是接口请求体?)
      • [2.4.2 常用接口请求体应用场景 ✨✨✨](#2.4.2 常用接口请求体应用场景 ✨✨✨)
      • [2.4.3 json 类型接口请求体构造](#2.4.3 json 类型接口请求体构造)
    • [2.5 接口响应断言](#2.5 接口响应断言)
  • 总结

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。



本文开始

1. RESTAssure测试框架介绍-Java

RESTAssure: Java自动化测试框架

推荐使用RESTAssure测试框架原因:

1.是由 Java 实现的 REST API 测试框架。

2.支持发起 POST, GET, PUT, DELETE 等请求。

3.可以用来验证和校对响应信息

RESTAssure官网地址:http://rest-assured.io/

RESTAssure优势:

1.支持多种数据格式:支持 xml/json 的结构化解析。

2.内置断言库:支持 xpath/jsonpath/gpath 解析方式。

3.可与多种测试框架集成:支持与 JUnit、TestNG 等测试框架集成

接口自动化测试缺点:

接口关注数据无法触达用户体验

2. RESTAssure测试框架使用

2.1 REST-assure环境准备:

测试环境准备:

1.创建 maven 项目。

2.基于 JDK、JUnit5。

3.pom.xml 添加 rest-assured 的依赖

xml 复制代码
<!-- rest-assured 相关依赖 -->
<properties>
    <rest-assured.version>5.3.0</rest-assured.version>
</properties>

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>${rest-assured.version}</version>
</dependency>

较完整的测试依赖:直接使用-复制到pom.xml文件即可

xml 复制代码
<!-- 其他使用到的依赖配置  -->
<!--   版本配置-->
<properties>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    <java.version>11</java.version>
    <junit.jupiter.version>5.9.2</junit.jupiter.version>
    <maven.compiler.version>3.11.0</maven.compiler.version>
    <maven-surefire-plugin.version>3.0.0</maven-surefire-plugin.version>
    <rest-assured.version>5.3.0</rest-assured.version>
    <json-path.version>2.8.0</json-path.version>
    <!-- allure报告 -->
    <allure.version>2.21.0</allure.version>
    <aspectj.version>1.9.19</aspectj.version>
    <allure.maven.version>2.12.0</allure.maven.version>
    <allure.cmd.download.url>
        https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline
    </allure.cmd.download.url>
</properties>
<dependencyManagement>
    <!--        junit5 版本管理, 找到对应依赖关系的 pom 文件,为了解决依赖冲突问题-->
    <dependencies>
        <dependency>
            <groupId>org.junit</groupId>
            <artifactId>junit-bom</artifactId>
            <version>${junit.jupiter.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>

    <!--        junit 相关依赖下载-->
    <!-- junit5 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- junit5-suite -->
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-suite</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- 用做兼容老版本 -->
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- rest-assured -->
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>${rest-assured.version}</version>
        <scope>compile</scope>
    </dependency>
    <!-- json path 解析json文件 -->
    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
        <version>${json-path.version}</version>
    </dependency>
    <!--        allure报告-->
    <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-junit5</artifactId>
        <version>${allure.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>${aspectj.version}</version>
    </dependency>

</dependencies>
<build>
    <plugins>
        <!--            maven 命令行执行插件-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${maven-surefire-plugin.version}</version>
            <configuration>
                <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                </argLine>
            </configuration>
            <!--                防止maven与junit5使用依赖冲突的问题-->
            <dependencies>
                <dependency>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                    <version>${junit.jupiter.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                    <version>${junit.jupiter.version}</version>
                </dependency>
            </dependencies>
        </plugin>
        <!--            maven 编译使用插件-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.version}</version>
            <configuration>
                <parameters>true</parameters>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <encoding>${maven.compiler.encoding}</encoding>
            </configuration>
        </plugin>

        <plugin>
            <groupId>io.qameta.allure</groupId>
            <artifactId>allure-maven</artifactId>
            <version>${allure.maven.version}</version>
            <configuration>
                <reportVersion>${allure.version}</reportVersion>
                <allureDownloadUrl>${allure.cmd.download.url}/${allure.version}/allure-commandline-${allure.version}.zip</allureDownloadUrl>
            </configuration>
        </plugin>
    </plugins>
</build>

2.2 REST-assure三剑客使用

2.2.1 接口请求方式

接口请求方式:客户端通过不同的HTTP请求方法向服务器获取/提供某种资源的方式;不同的请求方法,应用场景不同;所以针对不同的接口,能够准确满足该接口要求的请求方法

2.2.2 REST-assure的接口请求方法

请求方式 方法说明
when().get(URL) 构造 HTTP 协议中的 GET 请求
when().post(URL) 构造 HTTP 协议中的 POST 请求。
when().put(URL) 构造 HTTP 协议中的 PUT 请求。
when().delete(URL) 构造 HTTP 协议中的 DELETE 请求。

2.2.3 什么是请求参数构造

从URL中了解请求参数:

协议:ip/路径?参数

https://editor.csdn.net/md?not_checkout=1\&spm=1011.2415.3001.6192

1.接口请求参数在路径之后使用?代表客户端向服务端传递的参数。

2.使用 key=value 形式拼接在 URL 中,如果有多个,则使用&分隔,如上述;

请求参数使用场景:条件查询接口;鉴权接口;

2.2.4 如何发送携带参数的请求

  • 方式一:直接拼接在 URL 中:
    ?username=Hogwarts&id=666
  • 方式二:通过given()的queryParam()传递:
    queryParam():单个URL参数,方法参数String
    queryParams():多个URL参数,方法参数接收一个map对象
    【注】参数实际值,可以看具体方法要求,有多种;

参数传递代码示例:

java 复制代码
	 /**
     * 2. 通过queryParam()方法完成URL,参数传递
     *  then():请求之前准备工作
     */
    @Test
    void paramTest() {
        given()
            .queryParam("name", "zs")
            .queryParam("age", "19")
        .when()
            .get("https://httpbin.com/get")
        .then()
            .log().all();
    }

    /**
     * 3. 通过queryParams()方法完成URL,参数传递
     *  then():请求之前准备工作
     */
    @Test
    void paramsTest() {
        HashMap<String, String> queryParam = new HashMap<>();
        queryParam.put("name", "zhangSan");
        queryParam.put("age", "18");
        given()
            .queryParams(queryParam)
             //打印所有"请求"信息 - 用于调试
            .log().all()
        .when()
            .get("https://httpbin.com/get")
        .then()
            .log().all();
    }

2.2.5 REST-assure方法使用

REST-assure主要调用方法:

given():请求前做到准备工作 ,准备数据等

when():发起对应请求

then():验证请求返回的结果

java 复制代码
given()
    // given 设置测试预设
    .header("Hello", "zs")
.when()
    // when 所要执行的请求动作
    .get("https://httpbin.com/get")
.then()
    // then 解析结果、断言
    .log().all();  // 打印全部响应信息(响应头、响应体、状态等等)

准备→执行→反馈(结果)

  • given()方法:

    • 打印请求全部日志: log().all()
    • URL请求参数: queryParam()
    • 设置 Content-Type(): contentType()
    • 添加 header: headers()
    • 添加cookie: cookie()
    • 请求体: body()
  • when()方法:

    • get请求: get()。
    • post请求: post()。
    • put请求: put()。
    • delete请求: delete()
  • then()方法:

    • 打印全部日志: log().all()
    • 验证响应: body()
    • 验证响应状态码: statusCode()

2.3 接口请求头

  • 接口自动化化测试中,请求头关注哪些信息?/ 请求头有什么信息?

2.3.1 什么是请求头?

  1. HTTP 请求头:是在 HTTP 请求消息中包含的元数据信息,用于描述请求或响应的一些属性和特征。
  2. 实际工作过程中具体要关注的头信息字段需要和研发沟通。

常见的请求头信息: ✨✨✨

内容 含义
Authorization 表示客户端请求的身份验证信息
Cookie 表示客户端的状态信息,通常用于身份验证和会话管理
Content-Type 表示请求消息体的 MIME 类型
User-Agent 发送请求的客户端软件信息,如浏览器版本,操作系统等
其他 根据接口文档设计要求决定其作用

2.3.2 请求头使用场景:

1.身份认证:可能会将身份信息放到请求头中

2.指定请求数据类型:content-type:可能指定String, json等格式

2.3.3 接口请求头构造方法:

  1. 直接使用参数:使用方法.headers(string, object),参数直接放入键值对,构造单个请求参数或多个参数
java 复制代码
 @Test
    void header(){
        given()
        	.headers("Authorization", "verifyMessage")
         	.headers("name", "zs")
            .log().all()
        .when()
             .get("https://httpbin.com/get")
        .then()
             .log().all();
    }
  1. 使用HashMap构造
    使用headers(map)方法,参数为Map对象
java 复制代码
 void headerMap(){
        HashMap<String, String> headerMap = new HashMap<>();
        headerMap.put("Authorization", "verifyMessage");
        headerMap.put("name", "zs");
        headerMap.put("add", "request-header");
        given()
        	.headers(headerMap)
        	.log().all()
        .when()
            .get("https://httpbin.com/get")
        .then()
            .log().all();
    }

2.4 接口请求体

2.4.1 什么是接口请求体?

接口请求体:是进行 HTTP 请求时,发送给服务器的数据。

数据格式类型有: JSON、XML、文本、图像等格式。

【注】请求体的格式和内容取决于服务器端 API 的设计和开发人员的要求。

2.4.2 常用接口请求体应用场景 ✨✨✨

类型 介绍 Content-type
JSON(JavaScript Object Notation) 轻量级的数据交换格式,最常见的一种类型。 application/json
表单数据(Form Data) 以键值对的形式提交数据,例如:通过 HTML 表单提交数据。 application/x-www-form-urlencoded
XML(eXtensible Markup Language) 常用的标记语言,通常用于传递配置文件等数据。 application/xml,text/xml
文件(File) 可以通过请求体上传文件数据,例如:上传图片、视频等文件。 上传文件的 MIME 类型,例如 image/jpeg结合multipart/form-data ;适用表单+文件
纯文本(Text) 纯文本数据,例如发送邮件、发送短信等场景 text/plain
其他格式 二进制数据、protobuf 等格式
  • Json是什么:是 JavaScript Object Notation 的缩写。
    是一种轻量级的数据交换格式,是理想的接口数据交换语言。
    Content-Type 为 application/json。

2.4.3 json 类型接口请求体构造

REST-assure使用方法:given().body(jsonData)添加请求体信息:参数json格式的字符串

1.参数构造方式一:手动构造JSON 对象,参数得使用jsonData.toString()

使用场景:适用简单需要直接构造Json,不复杂的场景

java 复制代码
    /**
     * 使用场景:适用直接构造Json,不复杂场景,
     * 请求体中传Json
     *  通过body()方法,向请求体中传递参数
     */
    @Test
    void postJsonByObject() {
        JSONObject jsonData = new JSONObject();
        jsonData.put("name", "zs");
        jsonData.put("age", "18");

        given()
             //传递实参是Json字符串
            .body(jsonData.toString())
            .log().all()
        .when()
            .post("https://httpbin.com/post")
        .then()
            .log().all();
    }

2.参数构造方式二:直接复制已有的请求体-String ,

获取路径:从接口文档中获取已有请求体或者Web开发者工具中网络请求中获取等方式;

使用场景:复杂场景,有大量Json字段

java 复制代码
 /**
     * 使用场景:复杂场景,大量Json字段
     * 从现有的请求信息中复制
     */
    @Test
    void postJsonByString() {
        String jsonData = "{username: \"zs\", password: \"test12345\", code: 0}";
        given()
                //传递实参是Json字符串
            .body(jsonData)
            .log().all()
        .when()
            .post("https://httpbin.com/post")
        .then()
            .log().all();
    }

2.5 接口响应断言

  • 接口响应断言需要验证:
    -验证响应状态码。
    -验证响应体返回字段信息是否符合业务需求。
    -验证响应体字段的数据类型、数据格式。

【注】响应状态码存在于响应报文中,不是响应体中,响应体中的是开发返回的业务状态码,代表特殊含义;

1.响应报文中响应状态码含义:服务端返回的状态信息,判断请求是否成功;

2.响应体中的状态码:后端为了一些特殊情况,搞的状态码,如1001之类

  • 为什么需要接口断言?
    确保接口返回的数据符合预期。
    检测接口是否正常运行。
    提高测试效率。

2.5.1 接口响应断言方式

  • 断言状态码方法: then().statusCode(int);参数为为int可直接填写
  • 断言响应头方法: then().header()
  • 断言响应体内容方法: then().body()

断言响应状态码代码示例:

java 复制代码
	/**
     * 判断响应状态
     */
    @Test
    void testStatus() {
        given()
        .when()
            .get("https://httpbin.com/get")
        .then()
             .statusCode(200).log().all();

2.5.2 Json响应体断言

实际工作中,断言需要验证响应状态码,响应体正确

2.5.2.1.什么是接口响应体?

接口响应体:服务器端响应客户端请求后返回的数据体。

接口响应体的格式通常为 JSON、XML、HTML 等。

  • 为什么对响应体进行断言?
    1.验证响应体返回字段信息是否符合预期的业务需求。
    2.验证响应体字段的数据类型、数据格式。
    3.提高测试效率。
2.5.2.2Json响应体断言方法
2.5.2.2.1. 直接断言: then().body()。
  • 直接断言: then().body()。

    1.断言需要结合 hamcrest 使用。

    2.body("提取gpath的信息/实际结果", 预期结果操作)。

    3.使用 gpath 语法提取 - 了解即可,只能应用于简单场景;

  • 常用hamcrest方法:

    1.断言是否相等: equalTo()

    2.断言是否包含:hasItems()

    【注】静态方法都来自于 org.hamcrest.Matchers包

【注】

嵌套断言:json.code ; 获取json下code

数组断言:json.code[1];

gpath语法:.代表下一级,如上述:json下的code,code中第二个元素

响应体结果示例:

xml 复制代码
{
  "status": "success",
  "data": {
    "name": "John Doe",
    "age": 30,
    "email": "john.doe@example.com",
    "json": {
      "code": [1,2,3,4],
      "username": "test",
      "password": "test123",
    }
    "url": "https://httpbin.com/get"
  }
}

直接断言代码示例:

java 复制代码
 @Test
 void testBody(){
     given()
     	.body(jsonData)
     .when()
         // 发起GET请求
      	 .get("https://httpbin.com/get")  
      .then()
      	  // 结合hamcrest响应体断言
         .body("json.username", equalTo("test"));
     	   // 打印响应结果
         .log().all()  
 }
2.5.2.2.2.提取后断言then().extract().path():
  • then().extract().path():
    • extract(): 提取方法,extract()方法返回值是Response对象.
    • path(): 从返回值中提取想要的信息(使用 gpath 语法)

【注】extract()方法只负责提取,具体提取内容有path()方法决定;两者配合使用;

path(): 参数是提取的表达式,如提取json中的username

提取的值可作为入参,也可作为断言参数

提取后断言代码示例:嵌套提取+数组提取

java 复制代码
// 响应嵌套提取。
@Test
 void extractJson(){
     String jsonData = "{\"username\":\"test\",\"password\":\"test123\",\"code\":[1,2,3]}";
     ArrayList data = given()
     		.body(jsonData)
     .when()
             .post("https://httpbin.com/post")
     .then()
             .log().all()
             .extract().path("json.code");
     System.out.println(data);
 }
// 提取数组中的元素。
@Test
void extractArray(){
    String jsonData = "{\"username\":\"test\",\"password\":\"test123\",\"code\":[1,2,3]}";
    Integer data = given()
       .body(jsonData)
    .when()
       .post("https://httpbin.com/post")
    .then()
       .log().all()
       .extract().path("json.code[0]");
    System.out.println(data);
}

总结

✨✨✨各位读友,本篇分享到内容是否更好的帮助你理解,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
🎉🎉🎉一遇挫折就灰心丧气的人,永远是个失败者。而一向努力奋斗,坚韧不拔的人会走向成功。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!

相关推荐
wa的一声哭了2 小时前
内积空间 内积空间二
java·开发语言·python·spring·java-ee·django·maven
SadSunset2 小时前
Git常用命令
java·学习
晓13132 小时前
后端篇——第二章 Maven高级全面教程
java·maven
普兰店拉马努金2 小时前
【高中数学/排列组合】由字母AB构成的一个6位的序列,含有连续子序列ABA的序列有多少个?
java·排列组合
二等饼干~za8986682 小时前
GEO优化---关键词搜索排名源码开发思路分享
大数据·前端·网络·数据库·django
cike_y2 小时前
Spring使用注解开发
java·后端·spring·jdk1.8
程序员柒叔2 小时前
Dify 集成-向量数据库
数据库·milvus·向量数据库·工作流·dify·向量库
月明长歌2 小时前
MySQL 视图:把复杂查询封装成表,并且还能控权限、做解耦
数据库·mysql
l1t2 小时前
postgresql 18版bytea 类型转换的改进
数据库·postgresql