网站首页 > java教程 正文
前言
在上篇文章 <REST-Assured,接口自动化的 "瑞士军刀"- 初识篇 > REST-Assured,接口自动化的 "瑞士军刀"- 初识篇 中有介绍了 REST-Assured 测试框架及基础使用,没有了解的小伙伴可以先去看看,这篇将带着大家一起来学习 REST-Assured 测试框架强大的断言机制。
Hamcrest 与 REST-Assured
Hamcrest 是一款用于编写匹配器对象的框架,可以组合创建灵活的匹配器进行断言。
官方网址:http://hamcrest.org/
可以支持 Java、Python、Ruby、Objective-C 等语言
类似于 TestNG 单元测试框架或者 Junit 单元测试框架中所提供的 Assert 类,比如 TestNG 提供的断言匹配方法:
Assert.assertTrue();
Assert.assertFalse();
Assert.assertEquals();
...
先举几个在 REST-Assured 中用到的较多 Hamcrest 断言匹配方法:
//equalTo:基于传入对象的 equals 方法匹配方式,如果是数组则比较每个元素是否相等。
assertThat("lotto.lottoId", equalTo(5));
//hasItems:测试集合是否包含指定的多个元素
assertThat("lotto.winners.winnerId", hasItems(23, 54));
//...
更多的用法可以参考官方文档示例。
Hamcrest 相比较上述两款单元测试框架自带的断言匹配而言更加强大、优雅、易读。所以 REST-Assured 官方推荐使用的断言匹配就是 Hamcrest。
需要注意的是 REST-Assured 在使用 Hamcrest 的时候需要静态导入:
import static org.hamcrest.Matchers.*;
准备测试环境
我们拿官方文档中的例子来练习,JSON 返回数据如下:
{
"lotto":{
"lottoId":5,
"winning-numbers":[2,45,34,23,7,5,3],
"winners":[{
"winnerId":23,
"numbers":[2,45,34,23,3,5]
},{
"winnerId":54,
"numbers":[52,3,12,11,18,22]
}]
}
}
为了方便我们练习,我们可以使用 PostMan 模拟 Mock,定制我们想要的响应数据(Json/XML)
以 PostMan 模拟接口 JSON 响应为例,REST-Assured 发起请求:
given().
when().
get("https://013844de-a0b4-426b-b5dc-dcd3a2e5afe5.mock.pstmn.io/json").
then().
log().all();
控制台的输出的返回响应结果:
HTTP/1.1 200 OK
Date: Fri, 16 Oct 2020 10:08:18 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: nginx
x-srv-trace: v=1;t=7889c71dfff0bf98
x-srv-span: v=1;s=9305333febed8b23
Access-Control-Allow-Origin: *
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1602842942
ETag: W/"2d1-xSYx3nsyyhHEU4lc3Wu1ZhmyStM"
Vary: Accept-Encoding
Content-Encoding: gzip
{
"lotto": {
"lottoId": 5,
"winning-numbers": [
2,45,34,23,7,5,3
],
"winners": [
{
"winnerId": 23,
"numbers": [
2,45,34,23,3,5
]
},
{
"winnerId": 54,
"numbers": [
52,3,12,11,18,22
]
}
]
}
}
JSON 响应断言
需要注意的是 REST-Assured 中的 JSON 响应提取是为 Groovy's GPath 语法(简称 GPath),而不是 Jayway's JsonPath 语法。
那么 GPath 到底是什么?以下来自官网的说明
GPath is a path expression language integrated into Groovy which allows parts of nested structured data to be identified. In this sense, it has similar aims and scope as XPath does for XML. The two main places where you use GPath expressions is when dealing with nested POJOs or when dealing with XML
简单来说 GPath 是一种路径表达式语言,类似于 xpath,GPath 不仅可以应用于 XML,还可以应用于嵌套的层级结构(比如 JSON、HTML)。
Gpath 相比较 Jayway's JsonPath 语法更为简洁
比如:验证 lottoId 为 5
given().
when().
get("https://013844de-a0b4-426b-b5dc-dcd3a2e5afe5.mock.pstmn.io/json").
then().
assertThat().body("json.lotto.lottoId",equalTo(5));
比如:验证 winnerId 为 23 和 54
//前面部分代码跟上述一致,省略
assertThat().body("json.lotto.winners.winnerId",hasItems(23,54));
如果想要断言第一个 winnerId 为 32,我们可以通过索引访问:
assertThat().body("json.lotto.winners.winnerId[0]",equalTo(23));
还可以通过 greatThan 断言大于某个值
assertThat().body("json.lotto.winners.winnerId[0]",greaterThan(20));
复杂的 JsonPath 解析和验证:
- findAll
- 筛选符合后面条件的所有项,比如:查找 winnerId 大于 40 的项为 54
- assertThat().body("json.lotto.winners.findAll{it.winnerId > 40}.winnerId[0]",equalTo(54));
- 解释:
- findAll{it.winnerId > 40}表示对 winners 集合进行条件筛选,其中 it 表示 winners 本身
- 由于 findAll 筛选的结果也是集合,所以 winnerId 后面需要加索引
- find
- 筛选符合后面条件的第一项
- 用 find 完成上述的需求:
- assertThat().body("json.lotto.winners.find{it.winnerId > 40}.winnerId",equalTo(54));
- sum
- 对集合中所有项求和
- assertThat().body("json.lotto.winning-numbers.sum()",equalTo(119));
- 当然也可以和条件筛选结合:
- assertThat().body("json.lotto.winners.findAll{it.winnerId > 20}.winnerId.sum()",equalTo(77));
- max/min
- 求得集合中最大/最小的项
- assertThat().body("json.lotto.winning-numbers.max()",equalTo(45));
XML 响应断言
由于 XML 响应获取指定值也是使用 GPath 的语法来描述的,所以和上述的语法基本一致。
我们还是拿官网的示例来练习,有如下 XML 文件内容:
<shopping>
<category type="groceries">
<item>Chocolate</item>
<item>Coffee</item>
</category>
<category type="supplies">
<item>Paper</item>
<item quantity="4">Pens</item>
</category>
<category type="present">
<item when="Aug 10">Kathryn's Birthday</item>
</category>
</shopping>
验证第二个 category 节点的第一个 item 值为 Paper
given().
when().
get("https://013844de-a0b4-426b-b5dc-dcd3a2e5afe5.mock.pstmn.io/xml").
then().
assertThat().body("shopping.category[1].item[0]",equalTo("Paper"));
XML 还可以根据属性进行条件筛选,比如选出第一个 type 属性值为 groceries 节点的所有 item 文本
assertThat().body("shopping.category.find{it.@type=='groceries'}.item",hasItems("Chocolate","Coffee"));
有时候我们还可以采用简写:
assertThat().body("shopping.category.findAll{it.@type=='groceries'}",hasItems("Chocolate","Coffee"));
此表达式相比较上述的少了 item,原因在于在 category 节点上将会自动执行 toString()方法,将会获取 category 节点的所有子节点的文本值。
还有些时候我们在写路径的时候由于路径过长,整个表达式过于复杂,我们可以采取类似于 xpath 的相对路径写法,官方命名为深度优先搜索算法,其具体用法是以"**"开头,后面加上条件筛选即可。
比如:上面的例子使用深度优先搜索:
assertThat().body("**.find { it.@type == 'groceries' }",hasItems("Chocolate","Coffee"));
通过 find 找到符合筛选条件的第一个对应节点。
猜你喜欢
- 2024-11-05 Java 进阶之异常处理(java中异常处理)
- 2024-11-05 为什么Java中的const关键字没有实现?
- 2024-11-05 Spring Boot 内置工具类(springboot 工具类调用service)
- 2024-11-05 深入理解Java:注解(Annotation)基本概念(3-1)
- 2024-11-05 Spring Boot集成validation用于优雅的校验API参数的合法性
- 2024-11-05 java初学者,如何学习java?(java该怎么学)
- 2024-11-05 Nacos网关gateway的断言,自定义断言,过滤器使用
- 2024-11-05 恕我直言,在座的各位根本不会写 Java!
- 2024-11-05 JAVA 命令之标准选项(java怎么选择)
- 2024-11-05 Java锁与线程的那些“不可描述”的事儿
你 发表评论:
欢迎- 最近发表
-
- 五,网络安全IDA Pro反汇编工具初识及逆向工程解密实战
- 「JAVA8」- Lambda 表达式(java lambda表达式原理)
- 深入探讨Java代码保护:虚拟机保护技术的新时代
- Nginx反向代理原理详解(图文全面总结)
- 逆向拆解日本IT,哪些Java技术栈薪资溢价高
- mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比
- Spring Boot集成ProGuard轻松实现Java 代码混淆, Java 应用固若金汤
- 从 Java 代码逆向工程生成 UML 类图和序列图
- 人与人相处:尊重是标配,靠谱是高配,厚道是顶配
- Windows系统安装日期如何修改(windows10怎么修改安装日期)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)