当前位置: 首页 > news >正文

测试开发 | 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 上有这样一句简短的描述&#xff1a; Java DSL for easy testing of REST services 简约的 REST 服务测试 Java DSL 1.1 优点&#xff1a; REST Assured 官方的 README 第一句话对进行了一个优点的概述&#xff0c;总的…...

vue3:13、Vue3.3新特性-defineModel

旧版本的语法 新版本语法...

如何理解C++中的void*

1.什么是void* 首先void*中的void代表一个任意的数据类型&#xff0c;"星号"代表一个指针&#xff0c;所以其就是一个任意数据类型的指针。 其实就是一个未指定跳跃力的指针。 那void*的跳跃力又什么时候指定&#xff1f;在需要使用的时候指定就可以了&#xff0c…...

MVC,MVP,MVVM的理解和区别

MVC MVC &#xff0c;早期的开发架构&#xff0c;在安卓里&#xff0c;用res代表V&#xff0c;activity代表Controller层&#xff0c;Model层完成数据请求&#xff0c;更新操作&#xff0c;activity完成view的绑定&#xff0c;以及业务逻辑的编写&#xff0c;更新view&#xf…...

【TypeScript】一直提示 :无法重新声明块范围变量

【TypeScript】一直提示 &#xff1a;无法重新声明块范围变量 问题描述&#xff1a;在VSCode中编写ts代码时&#xff0c;编写保存完之后&#xff0c;通过tsc 文件名.ts编译就会看到变量名下面出现了红色的波浪线&#xff0c;提示的内容是无法重新声明块范围变量。 解决方法&am…...

【python自动化】七月PytestAutoApi开源框架学习笔记(一)

前言 本篇内容为学习七月大佬开源框架PytestAutoApi记录的相关知识点&#xff0c;供大家学习探讨 项目地址&#xff1a;https://gitee.com/yu_xiao_qi/pytest-auto-api2 阅读本文前&#xff0c;请先对该框架有一个整体学习&#xff0c;请认真阅读作者的README.md文件。 本文…...

Python学习 -- logging模块

logging 模块是 Python 中用于记录日志的标准库&#xff0c;它提供了丰富的功能&#xff0c;可以帮助开发者进行日志记录和管理。以下是关于logging模块的详细使用方式&#xff0c;包括日志级别、处理流程、Logger 类、Handler 类、Filter 类、Formatter 类以及模块中常用函数等…...

【socket】getaddrinfo、getsockname、getpeername对比

这三个函数都是在网络编程中用来获取地址信息的&#xff0c;但是它们的使用场景和功能有所不同。getaddrinfo(): 这个函数主要用于将一个主机名&#xff08;或者 IP 地址&#xff09;和端口号转换成适用于 socket() 函数的一个或多个套接字地址结构。它能够处理 IPv4 和 IPv6 地…...

【MySQL】表的增删改查(进阶)

表的增删改查&#xff08;进阶&#xff09; 一. 数据库约束1. 约束类型2. NULL约束3. UNIQUE&#xff1a;唯一约束4. DEFAULT&#xff1a;默认值约束5. PRIMARY KEY&#xff1a;主键约束6. FOREIGN KEY&#xff1a;外键约束7. CHECK约束 二. 表的设计1. 一对一2. 一对多3. 多对…...

关于安卓13中Android/data目录下的文件夹只能查看无法进行删改的问题

前言 因为升级了安卓13&#xff0c;然后有个app需要恢复数据&#xff0c;打算和以前一样直接删除Android/data下对应目录再添加&#xff0c;结果不行&#xff0c;以下是结合网上以及自己手机情况来做的一种解决方案。 解决 准备&#xff1a; 待恢复app&#xff08;包名com.…...

Vulnhub: Masashi: 1靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.236 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.236查看80端口的robots.txt提示三个文件 snmpwalk.txt内容&#xff0c;tftp服务在1337端口 sshfolder.txt内容&#xff0c…...

校园二手物品交易系统微信小程序设计

系统简介 本网最大的特点就功能全面&#xff0c;结构简单&#xff0c;角色功能明确。其不同角色实现以下基本功能。 服务端 后台首页&#xff1a;可以直接跳转到后台首页。 用户信息管理&#xff1a;管理所有申请通过的用户。 商品信息管理&#xff1a;管理校园二手物品中…...

Pixillion Pro for Mac:将您的图像转换为艺术佳作

Pixillion for Mac有着非常强大的图像转换功能和简单的使用方法&#xff0c;帮助你快速完成大批量图像转换的工作&#xff0c;支持一键转换jpeg、jpg、bmp、png、gif、raf、heic等各种格式的图像文件&#xff0c;同时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年&#xff0c…...

每日刷题-2

目录 一、选择题 二、编程题 1、倒置字符串 2、排序子序列 3、字符串中找出连续最长的数字串 4、数组中出现次数超过一半的数字 一、选择题 1、 题目解析&#xff1a; 二维数组初始化的一般形式是&#xff1a; 数据类型 数组名[常量表达式1][常量表达式2] {初始化数据}; 其…...

AOSP内置搜狗输入并设置默认输入法

前期准备 AOSP分支&#xff1a;aosp13_r7 系统版本&#xff1a;Ubuntu 22.04.1 LTS 工具&#xff1a;手&#xff0c;vscode&#xff0c;winscp(因为我是用的服务器编译) 下载搜狗输入法 思路&#xff1a; 1.集成搜狗输入法到aosp 2.删除系统输入法 3.设置搜狗输入法为默…...

ICCV 2023|通过慢学习和分类器对齐在预训练模型上进行持续学习

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 作者介绍 张耕维 悉尼科技大学在读博士生&#xff0c;研究方向为持续学习 报告题目 通过慢学习和分类器对齐在预训练模型上进行持续学习 内容简介 持续学习研究的目标在于提高模型利用顺序到达的数据进行学习的…...

蓝桥杯打卡Day5

文章目录 日志排序重复者 一、日志排序IO链接 本题思路:本题就是根据就是排序的知识点&#xff0c;在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软件&#xff0c;因为一些特殊的原因&#xff0c;在这里简单的记录一哈自己开发apk的流程和心得。 首先说明我采用的环境有哪些&#xff1f; 1、QT的版本&#xff0c;个人建议5.15.2的版本及以上&#xff0c;我是用的5.15.2。 2、andriod studio 可以…...

【广州华锐互动】AR技术在配电系统运维中的应用

随着科技的不断发展&#xff0c;AR(增强现实)技术逐渐走进了我们的生活。在电力行业&#xff0c;AR技术的应用也为巡检工作带来了许多新突破&#xff0c;提高了巡检效率和安全性。本文将从以下几个方面探讨AR配电系统运维系统的新突破。 首先&#xff0c;AR技术可以实现虚拟巡检…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...

python基础语法Ⅰ

python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器&#xff0c;来进行一些算术…...