测试开发 | Java 接口自动化测试首选方案:REST Assured 实践


1 . 初识 REST Assured
在 REST Assured 的官方 GitHub 上有这样一句简短的描述: Java DSL for easy testing of REST services 简约的 REST 服务测试 Java DSL
1.1 优点:
REST Assured 官方的 README 第一句话对进行了一个优点的概述,总的意思表达的就是简单好用。那么 REST Assured 有哪些优点,又该如何使用呢?

用 Java 做接口自动化测试首选 REST Assured,具体原因如下:
开源
简约的接口测试 DSL
支持 xml json 的结构化解析
支持 xpath jsonpath gpath 等多种解析方式
对 spring 的支持比较全面
功能很齐全,部分我自己也还没有具体用到,了解到了方向,需要时随时查找学习
2. 如何使用
添加 maven 依赖
<dependency><groupId>io.rest-assured</groupId><artifactId>rest-assured</artifactId><version>4.0.0</version><scope>test</scope>
</dependency>
2.1 基本三步曲
我们对接口进行测试一般由三步曲:传参、发请求、响应结果断言,REST Assured给我们提供了清晰的三步曲,以given、when、then的结构来实现,基本写法如下:
//使用参数
given().param("key1", "value1").param("key2", "value2").
when().post("/somewhere").
then().body(containsString("OK"))//使用X-Path (XML only)
given().params("firstName", "John", "lastName", "Doe").
when().post("/greetMe").
then().body(hasXPath("/greeting/firstName[text()='John']"))
2.2 分步拆解
前提:现有一个post请求的登录接口。
http://47.103.xxx.133/auth/oauth/token,
请求体body如下
{"password": "elcrD28ZSLLtR0VLs/jERA\u003d\u003d\n","grant_type": "password","scope": "server","userType": 1,"username": "xxx"
}
Request Header 如下:
Headers: Authorization=Basic c3lzdGVtxxxRlbQ==Host=47.103.xxx.133Accept=*/*Content-Type=application/json; charset=ISO-8859-1
分步拆解一
Givern
我们发送请求经常需要带有参数,使用 given() 就可以实现,当时当我们使用 given() 的时候发现其中有很多传参方法如下:

没错,在传参的方法中包含了 param、pathParam、queryParam 和 formParam,下面来研究下这几个传参方法的区别
param
通常我们都会使用 given().param 方法来传参,REST Assured 会根据 HTTP 方法自动尝试确定哪种参数类型(即查询或表单参数),如果是 GET,则查询参数将自动使用,如果使用 POST,则将使用表单参数;
queryParam 和 formParam
有时候在 PUT 或 POST 请求中,需要区分查询参数和表单参数时,就需要使用queryParam 和 formParam 方法了,具体写法如下:
given().formParam("formParamName", "value1").queryParam("queryParamName", "value2").
when().post("/something")
pathParam
使用given时指定请求路径的参数,这个方法很少用到,或者说我本人几乎没用到过(可能我的修行还不够,踩坑还太少~);具体写法如下:
given().pathParam("OAuth", "oauth").pathParam("accessToken", "token").
when(). post("/auth/{OAuth}/{accessToken}").
then()...
header/headers
经常还需要在请求头中带入参数,这个时候就可以使用header或headers方法,写法如下:
given().header("Authorization","Basic c3lzdGVtOxxxbQ==").header("Host","47.xxx.xxx.133")
或者用headers将多个参数写在一起:
given().headers("Authorization","Basic c3lzdGVtxxx3RlbQ==","Host","47.xxx.xxx.133")
cookie
有时候需要在请求中带入cookie,restassured提供了cookie方法来实现:
given().cookie("c_a","aaaaaa").cookie("c_b","bbbbbb"). ..
contentType
经常还会设置contentType,最常见的就是application/json了,写法如下:
given().contentType("application/json"). ..
//或者
given().contentType(ContentType.JSON). ..
body
在POST, PUT 或 DELETE请求中,我们经常还需要带上请求体body,写法如下:
given().body("{\n" +"\t\"password\": \"elcrD28xxxR0VLs/jERA\\u003d\\u003d\\n\",\n" +"\t\"grant_type\": \"password\",\n" +"\t\"scope\": \"server\",\n" +"\t\"userType\": 1,\n" +"\t\"username\": \"xxx\"\n" +"}")
也可以用request更为明确的指出是请求body:
given().request().body("{\n" +"\t\"password\": \"elcrD28xxxR0VLs/jERA\\u003d\\u003d\\n\",\n" +"\t\"grant_type\": \"password\",\n" +"\t\"scope\": \"server\",\n" +"\t\"userType\": 1,\n" +"\t\"username\": \"xxx\"\n" +"}")
没有参数
如果我们没有参数需要传递,也可以省略掉given():
get("/lotto").then().assertThat().body("lotto.lottoId", equalTo(5));
proxy
有时候我们需要进行接口的调试,抓包是最常用的一种方式,rest-assured 提供了 proxy 方法,可以设置代理,写法如下:
given().proxy("127.0.0.1",8888). ..
实际运行结果:


分步拆解二
When
when主要用来触发请求,在when后面接着请求URL:
given().when().post("http://47.103.xxx.133/auth/oauth/token"). ..
前面在 given 中我们设置了很多请求参数,在 when 中也可以设置,只不过要注意的是在请求之前设置;这也比较好理解,如果再请求之后的话,参数都设置怎么发请求呢?
given().when().contentType(ContentType.JSON).headers("Authorization","Basic c3lzxxx3RlbQ==","Host","47.xxx.xxx.133").request().body("{\n" +"\t\"password\": \"elcrD28ZSLLtR0VLs/jERA\\u003d\\u003d\\n\",\n" +"\t\"grant_type\": \"password\",\n" +"\t\"scope\": \"server\",\n" +"\t\"userType\": 1,\n" +"\t\"username\": \"qinzhen\"\n" +"}").post("http://47.xxx.xxx.133/auth/oauth/token"). ..
分步拆解三
Then
then后面可以跟断言,也可以获取响应值
断言-then().body()
then().body() 可以对响应结果进行断言,在 body 中写入断言:
.. post("http://47.xxx.xxx.133/auth/oauth/token").then().statusCode(200).body("code",equalTo(1));
其中statusCode(200)是对状态码的断言,判断状态码是否为200; body(“code”,equalTo(1))是对返回体中的 code 进行断言,要求返回 code值为1 。
注:这里的equalTo使用的是hamcrest断言,不了解的小伙伴可参考另外一篇文章:Junit原生断言和hamcrest断言的区别及使用
实操演示:
我们将上述的 given、when、then 结合起来看一下实际运行效果,这里在运行之前再提一个功能,我们可以在 when 和 then 后面加上.log().all(),这样在运行过程中就可以把请求和响应的信息都打印出来:


获取响应-then().extract().body().path(“code”)
我们可以在 then 后面利用 .extract().body() 来获取我们想要 body 的返回值,它们也可以直接接在断言后面,写法如下:
注意这里的body() 不要和请求体body()以及断言的body()混淆了
.. .then().log().all().statusCode(200).body("code",equalTo(1)).extract().body().path("code");
实操演示:
演示前再来看一个新的功能,上面我们再写请求体 body 时时这样的:
body("{\n" +"\t\"password\": \"elcrD28ZxxxVLs/jERA\\u003d\\u003d\\n\",\n" +"\t\"grant_type\": \"password\",\n" +"\t\"scope\": \"server\",\n" +"\t\"userType\": 1,\n" +"\t\"username\": \"qinzhen\"\n" +"}")
看起来有点丑,改造一下;rest-assured 为我们提供了一个利用 HashMap 来创建json 文件的方法,先把要传的字段放入 hashmap 中,然后用 contentType 指明JSON 就可以了,具体写法如下:
HashMap map = new HashMap();
map.put("password","elcrD28ZSLLtR0VLs/jERA\u003d\u003d\n");
map.put("grant_type","password");
map.put("scope","server");
map.put("userType",1);
map.put("username","xxx");
given().headers("Authorization","Basic c3lzdGVtxxxlbQ==","Host","47.xxx.xxx.133").contentType(JSON).body(map). ..
现在进行完整的请求,获取返回值 code 并打印:
HashMap map = new HashMap();
map.put("password","elcrD28ZSLLtR0VLs/jERA\u003d\u003d\n");
map.put("grant_type","password");
map.put("scope","server");
map.put("userType",1);
map.put("username","xxx");
Integer code =
given().headers("Authorization","Basic c3lzdGVtxxxlbQ==","Host","47.xxx.xxx.133").contentType(JSON).body(map).
when().log().all().post("http://47.xxx.xxx.133/auth/oauth/token").
then().log().all().statusCode(200).body("code",equalTo(1)).extract().body().path("code");
System.out.println("返回code的值是:"+code);
运行结果:

推荐学习
关于REST Assured,这里仅仅算是初步认识。认识它的语法结构和功能,对于更多丰富的用法还需要慢慢探索研究,特别是断言的部分,是测试工程师最常用最终要的功能之一。REST Assured提供的完整断言手段,在后续文章中我们一起探讨。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章:
测试开发 | Java 接口自动化测试首选方案:REST Assured 实践
1 . 初识 REST Assured 在 REST Assured 的官方 GitHub 上有这样一句简短的描述: Java DSL for easy testing of REST services 简约的 REST 服务测试 Java DSL 1.1 优点: REST Assured 官方的 README 第一句话对进行了一个优点的概述,总的…...
vue3:13、Vue3.3新特性-defineModel
旧版本的语法 新版本语法...
如何理解C++中的void*
1.什么是void* 首先void*中的void代表一个任意的数据类型,"星号"代表一个指针,所以其就是一个任意数据类型的指针。 其实就是一个未指定跳跃力的指针。 那void*的跳跃力又什么时候指定?在需要使用的时候指定就可以了,…...
MVC,MVP,MVVM的理解和区别
MVC MVC ,早期的开发架构,在安卓里,用res代表V,activity代表Controller层,Model层完成数据请求,更新操作,activity完成view的绑定,以及业务逻辑的编写,更新view…...
【TypeScript】一直提示 :无法重新声明块范围变量
【TypeScript】一直提示 :无法重新声明块范围变量 问题描述:在VSCode中编写ts代码时,编写保存完之后,通过tsc 文件名.ts编译就会看到变量名下面出现了红色的波浪线,提示的内容是无法重新声明块范围变量。 解决方法&am…...
【python自动化】七月PytestAutoApi开源框架学习笔记(一)
前言 本篇内容为学习七月大佬开源框架PytestAutoApi记录的相关知识点,供大家学习探讨 项目地址:https://gitee.com/yu_xiao_qi/pytest-auto-api2 阅读本文前,请先对该框架有一个整体学习,请认真阅读作者的README.md文件。 本文…...
Python学习 -- logging模块
logging 模块是 Python 中用于记录日志的标准库,它提供了丰富的功能,可以帮助开发者进行日志记录和管理。以下是关于logging模块的详细使用方式,包括日志级别、处理流程、Logger 类、Handler 类、Filter 类、Formatter 类以及模块中常用函数等…...
【socket】getaddrinfo、getsockname、getpeername对比
这三个函数都是在网络编程中用来获取地址信息的,但是它们的使用场景和功能有所不同。getaddrinfo(): 这个函数主要用于将一个主机名(或者 IP 地址)和端口号转换成适用于 socket() 函数的一个或多个套接字地址结构。它能够处理 IPv4 和 IPv6 地…...
【MySQL】表的增删改查(进阶)
表的增删改查(进阶) 一. 数据库约束1. 约束类型2. NULL约束3. UNIQUE:唯一约束4. DEFAULT:默认值约束5. PRIMARY KEY:主键约束6. FOREIGN KEY:外键约束7. CHECK约束 二. 表的设计1. 一对一2. 一对多3. 多对…...
关于安卓13中Android/data目录下的文件夹只能查看无法进行删改的问题
前言 因为升级了安卓13,然后有个app需要恢复数据,打算和以前一样直接删除Android/data下对应目录再添加,结果不行,以下是结合网上以及自己手机情况来做的一种解决方案。 解决 准备: 待恢复app(包名com.…...
Vulnhub: Masashi: 1靶机
kali:192.168.111.111 靶机:192.168.111.236 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.236查看80端口的robots.txt提示三个文件 snmpwalk.txt内容,tftp服务在1337端口 sshfolder.txt内容,…...
校园二手物品交易系统微信小程序设计
系统简介 本网最大的特点就功能全面,结构简单,角色功能明确。其不同角色实现以下基本功能。 服务端 后台首页:可以直接跳转到后台首页。 用户信息管理:管理所有申请通过的用户。 商品信息管理:管理校园二手物品中…...
Pixillion Pro for Mac:将您的图像转换为艺术佳作
Pixillion for Mac有着非常强大的图像转换功能和简单的使用方法,帮助你快速完成大批量图像转换的工作,支持一键转换jpeg、jpg、bmp、png、gif、raf、heic等各种格式的图像文件,同时pixillion mac激活版还提供了图像旋转、添加水印、调整图像大…...
【上海迪士尼度假区】技术解决方案
开源平台地址Giteehttps://gitee.com/issavior/disney 技术解决方案 1. 背景2. 技术架构3. 业务架构3.1 架构图3.2 说明 4. 技术能力4.1 自研中间件4.2 定制化中间件 5. 领域模型6. 数据模型7. 交易链路8. 状态机8. 接口文档 1. 背景 上海迪士尼度假区已运营近10年,…...
每日刷题-2
目录 一、选择题 二、编程题 1、倒置字符串 2、排序子序列 3、字符串中找出连续最长的数字串 4、数组中出现次数超过一半的数字 一、选择题 1、 题目解析: 二维数组初始化的一般形式是: 数据类型 数组名[常量表达式1][常量表达式2] {初始化数据}; 其…...
AOSP内置搜狗输入并设置默认输入法
前期准备 AOSP分支:aosp13_r7 系统版本:Ubuntu 22.04.1 LTS 工具:手,vscode,winscp(因为我是用的服务器编译) 下载搜狗输入法 思路: 1.集成搜狗输入法到aosp 2.删除系统输入法 3.设置搜狗输入法为默…...
ICCV 2023|通过慢学习和分类器对齐在预训练模型上进行持续学习
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 作者介绍 张耕维 悉尼科技大学在读博士生,研究方向为持续学习 报告题目 通过慢学习和分类器对齐在预训练模型上进行持续学习 内容简介 持续学习研究的目标在于提高模型利用顺序到达的数据进行学习的…...
蓝桥杯打卡Day5
文章目录 日志排序重复者 一、日志排序IO链接 本题思路:本题就是根据就是排序的知识点,在sort内部可以使用仿函数来改变此时排序规则。 #include <bits/stdc.h>const int N10010; int n; std::string logs[N];int main() {std::ios::sync_with_stdio(false)…...
QT for andriod
QT for andriod 开发 apk软件,因为一些特殊的原因,在这里简单的记录一哈自己开发apk的流程和心得。 首先说明我采用的环境有哪些? 1、QT的版本,个人建议5.15.2的版本及以上,我是用的5.15.2。 2、andriod studio 可以…...
【广州华锐互动】AR技术在配电系统运维中的应用
随着科技的不断发展,AR(增强现实)技术逐渐走进了我们的生活。在电力行业,AR技术的应用也为巡检工作带来了许多新突破,提高了巡检效率和安全性。本文将从以下几个方面探讨AR配电系统运维系统的新突破。 首先,AR技术可以实现虚拟巡检…...
终极Galgame社区完整指南:从零开始构建你的视觉小说精神家园
终极Galgame社区完整指南:从零开始构建你的视觉小说精神家园 【免费下载链接】kun-touchgal-next TouchGAL是立足于分享快乐的一站式Galgame文化社区, 为Gal爱好者提供一片净土! 项目地址: https://gitcode.com/gh_mirrors/ku/kun-touchgal-next 还在为寻找纯…...
实战应用:基于快马AI与OpenClaw构建Mac本地电商价格监控系统
最近在做一个电商价格监控的小工具,发现用OpenClaw配合Mac本地环境搭建特别方便。这里分享一下我的实战经验,希望能帮到有类似需求的同学。 为什么选择OpenClaw OpenClaw是个轻量级的Python爬虫框架,特别适合需要快速搭建数据采集系统的场景…...
实战应用:基于快马平台ai,开发并部署一个功能齐全的instagram内容下载web应用
今天想和大家分享一个实战项目:基于InsCode(快马)平台快速开发并部署一个功能完备的Instagram内容下载Web应用。这个项目从需求分析到上线只用了不到半天时间,特别适合想验证产品原型的开发者。 项目需求分析 首先明确核心功能需求:需要支持I…...
宠物店主的福音:用LongCat一键生成宠物服装电商主图,省时省力
宠物店主的福音:用LongCat一键生成宠物服装电商主图,省时省力 1. 为什么宠物店主需要AI图片编辑工具 开宠物店的朋友们都知道,商品主图的质量直接影响销量。一件宠物小衣服,如果只是平铺拍摄或者随便套在模特身上,很…...
OpenClaw开源项目深度体验:对比其与星图GPU平台Qwen3-14B-Int4-AWQ部署差异
OpenClaw开源项目深度体验:对比其与星图GPU平台Qwen3-14B-Int4-AWQ部署差异 1. 项目概览与核心功能 OpenClaw是近期备受关注的开源大模型项目,主打轻量化和易部署特性。它采用混合专家架构(MoE),在保持模型性能的同时显著降低了计算资源需求…...
从云端到指尖:巧用Aspose组件实现Office/PDF文档秒级HTML预览,攻克移动端大文件访问瓶颈
1. 移动端大文件预览的痛点与解决思路 最近接手一个企业级项目时,遇到了一个非常典型的场景:用户通过PC端上传各种办公文档(Word、Excel、PPT、PDF),需要在移动端随时查看。但当文件体积较大时(比如超过50M…...
STM32F103红外小车避坑指南:从Proteus仿真失败到实物调试成功
STM32F103红外小车避坑指南:从Proteus仿真失败到实物调试成功 第一次尝试用STM32F103做红外循迹小车时,我花了整整三天时间在Proteus里调试仿真,结果连最基本的电机转动都实现不了。直到把电路搬到实物上,才发现仿真环境里那些看似…...
Umi-OCR:重新定义本地化文字识别的工作流范式
Umi-OCR:重新定义本地化文字识别的工作流范式 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。 …...
Pixel Couplet Gen部署案例:混合云架构(公有云API+私有云模型)方案
Pixel Couplet Gen部署案例:混合云架构(公有云API私有云模型)方案 1. 项目背景与价值 Pixel Couplet Gen是一款融合传统春节文化与现代像素艺术风格的AI春联生成器。该项目基于ModelScope大模型驱动,通过创新的8-bit像素游戏UI设…...
Go Channel 缓冲区机制与性能影响
Go Channel 缓冲区机制与性能影响 在Go语言中,Channel是协程间通信的核心机制,而缓冲区的设置直接影响程序的并发性能和稳定性。理解缓冲区的运作原理及其对性能的影响,对于编写高效、可靠的并发程序至关重要。本文将从缓冲区的底层机制出发…...
