使用JMeter进行压力测试系列文章:
目录
[5. JSON提取器](#5. JSON提取器)
[5.1 JSON操作符](#5.1 JSON操作符)
[5.2 JSON path Tester](#5.2 JSON path Tester)
[5.3 配置JSON提取器](#5.3 配置JSON提取器)
[5.4 JSON提取器的作用域](#5.4 JSON提取器的作用域)
[5.5 修改目录结构](#5.5 修改目录结构)
[6. 用户自定义变量](#6. 用户自定义变量)
[7. JSON断言](#7. JSON断言)
5. JSON提取器
在HTTP信息头管理器中手动配置的user_header不仅存在多用户登录时,不同用户登录凭证不同的问题,而且单用户登录身份认证信息也会过期,需要使用JSON提取器来完成用户登录凭证/身份信息的自动提取。
JMeter中将处理器分为前置处理器和后置处理器,核心在这个处理器是在取样器执行前还是后采才执行。JSON提取器只有获取到响应结果,才能去获取响应中的JSON值;
5.1 JSON操作符
常用的简单JSON操作符有:
|-----------|----------|
| 操作符 | 描述 |
| $ | 代表根元素 |
| @ | 代表当前元素 |
| * | 通配符,所有结点 |
| .<name> | 子元素 |
5.2 JSON path Tester
在监听器->查看结果树中,可以选择JSON path Tester进行JSON操作符表达式的测试,使用$.data即可提取data:

5.3 配置JSON提取器
需要提取的是登录接口响应数据中的data,创建一个JSON提取器,将提取出来的字符串存储到token变量中:

再修改之前创建的HTTP信息头管理器,将原来写定的值修改为{变量名},即{token}:

再次运行后查看查看结果树,可以正确获取用户登录凭证;
总结流程:从登录接口的返回值总提取data(即用户的登录凭证),存储到token变量中,再使用JSON提取器提取token变量,从而获取到用户的登录凭证,填写到获取博客列表接口的请求头中。
5.4 JSON提取器的作用域
JSON提取器会从它所在的作用域内的上一个响应中提取数据 。如果有多个接口中都存在符合条件的JSON提取字段,JSON提取器提取哪个响应取决于它的放置位置。
再创建一个HTTP请求取样器,目录结构如下:

查看"获取用户;列表"接口的请求头中的user_token:

这个data是获取博客列表接口的响应中的data,而不是博客系统登录接口的响应中的data。
5.5 修改目录结构
将JSON提取器移位,令其作为博客系统登录接口的子接口,并将HTTP信息头管理器也移位至于各HTTP取样器同级:

这样的结构下,JSON提取器将从登录接口中提取data作为token,HTTP信息头管理器通过${token}获取的user_token也就是用户的登录凭证,再次运行验证即可测试成功:

6. 用户自定义变量
对于一些多接口使用且需频繁修改的公共参数,可以使用用户自定义变量。比如本地回环、测试服、压测服多个ip,有时还需多个端口,就可以使用用户自定义变量定义多个ip地址,直接使用对应变量${服务器ip}即可;再比如一些全局固定配置:文件上传路径、业务常量等等,都可以使用用户自定义变量。
此处只进行简单示例,对于根据博客id获取该博客详情页接口,可以使用现在获取博客列表接口中使用JSON提取器的方式定义一个blogId变量的方式,也可以定义一个用户自定义变量id来实现:

在查看博客详情页使用${id}作为博客id:

运行后查看测试结果,可以在请求体的query string处查看到用户自定义变量id已被正确传递给后端变量blogId:

7. JSON断言
接口发送请求成功,响应码为200并不能完全代表接口请求成功,可以使用JSON断言来进一步判断接口响应数据是否符合预期。
JSON断言有以下选项:
|------------------------------------------------------|-------------------------|
| 选项 | 含义 |
| Assert JSON Path exists | 使用JSON提取器确定待断言的JSON |
| Additionally assert value | 匹配断言值 |
| Match as regular expression | 使用正则匹配 |
| Expected Value | 期望断言值 (严格大小写的具体值或正则表达式) |
| Expect null | 期望结果为空 |
| Invert assertion (will fail if above conditions met) | 结果取反 |
注:(1)若仅填写Assert JSON Path exists,则表示仅判断该字段是否存在;
(2)若Expected Value中填写的是正则表达式,则需要勾选Match as regular expression;
比如:在博客登录接口下创建一个JSON断言:正则表达式\S+表示匹配若干个(≥1)字符:

ps:关于接口测试的传参类型问题
由于前后端交互支持的多种传参类型,在使用测试工具进行测试时若参数类型不一致则无法正确测试,若后端采取的是对象传参,则对参数添加@RequestBody注解后,前端搭配设置contentType为application/json后即可使用json传参。
此处讨论后端使用普通类型参数传参的类型问题。
后端接口采取若干普通类型参数传参,前端则无需设置contentType,默认采取application/x-www-form-urlencoded格式,在使用postman或JMeter测试时,需要注意对应设置contentType的请求头,否则会由于格式不一致而无法正确传参。
后端接口如下:

前端ajax如下:

使用Chrome访问系统,使用添加博客功能,查看contentType:

在使用postman测试该接口时,须使用与前端一致的格式:

刷新前端页面即可看到对应信息:

再使用JMeter测试:
创建测试新增博客页的HTTP请求,application/x-www-form-urlencoded需要使用参数方式:
(若需使用application/json格式,则需使用消息体数据方式)

运行测试,在查看结果树中可以看到请求将对应参数分别赋值给了title和content参数:

刷新页面即可得到最新博客:
