浅谈断言之响应断言
在进行测试时,确保服务器响应的内容符合预期是至关重要的,这时就需要用到JMeter的断言功能。响应断言(Response Assertion)是JMeter中最常用的一种断言类型,它允许用户验证服务器响应数据是否包含(或不包含)特定的文本、模式或其他条件,以此来判断请求是否成功。
响应断言的基本概念
响应断言用于检查服务器响应的数据,根据设置的条件判断请求是否通过。它支持多种匹配模式,包括但不限于子字符串匹配、正则表达式匹配、响应代码匹配等。通过灵活配置响应断言,测试人员可以精确控制测试用例的成功标准。
响应断言的配置步骤
- 添加响应断言:
○ 在JMeter中打开你的测试计划,选择需要添加断言的取样器(例如HTTP请求)。
○ 右键点击该取样器,选择“添加” -> “断言” -> “响应断言”。 - 配置断言细节:
○ 名称: 给断言命名,便于识别。
○ Apply to: 选择断言应用的对象,如Main sample only(仅主样本)、Sub-samples(子样本)等,之前已经有专门的文章进行介绍。
○ 测试字段: 需要验证的响应部分,常见的选项有“Text Response”(响应文本)、“Document (text)”(文档文本,适用于HTML页面)、“Code”(响应代码)等。
○ 模式匹配规则: 匹配规则,如“Contains”(包含)、“Matches”(匹配)、“Equals”(等于)、“Not”(不包含/不匹配)等,具体响应断言的匹配模式及使用场景介绍如下
● 包含(Contains): 验证响应中是否包含指定的文本字符串。适用于检查响应中是否存在特定关键字或短语。
● 匹配(Matches): 使用正则表达式进行匹配,适合更复杂的文本模式验证。
● 相等(Equals): 验证响应内容是否与指定的字符串完全相同,常用于精确匹配测试。
● 字符串(Substring): 类似于Contains,但提供更灵活的子串匹配选项。
● 否(Not): 用于验证响应中不包含特定文本或不匹配特定模式。
● 或者(Or): 用于验证响应中包含A或者B这种特定模式。
○ 测试模式: 输入期望的文本或正则表达式。如果是多个模式,可以使用换行分隔。
○ 自定义失败消息: 自定义失败的内容。
应用实例
我们通过SpingBoot框架编写如下测试接口代码:
@PostMapping(value = "/login",produces = "application/json;charset=UTF-8")
public String authenticate(@RequestBody JSONObject request) {
String validUsername = "admin";
String validPassword = "password";
String response = "{\"total\":2,\"data\":[{\"id\":123,\"name\":\"John Doe\",\"email\":\"johndoe@example.com\",\"phone\":\"123-456-7890\",\"address\":{\"street\":\"123 Main St\",\"city\":\"New York\",\"state\":\"NY\",\"zip\":\"10001\"},\"interests\":[\"sports\",\"music\",\"travel\"]},{\"id\":456,\"name\":\"Jane Smith\",\"email\":\"janesmith@example.com\",\"phone\":\"987-654-3210\",\"address\":{\"street\":\"456 Elm St\",\"city\":\"Los Angeles\",\"state\":\"CA\",\"zip\":\"90001\"},\"interests\":[\"reading\",\"cooking\",\"hiking\"]}]}";
if (request.getString("username").equals(validUsername) && request.getString("password").equals(validPassword)) {
return response;
} else {
return response;
}
}
我们编写如下测试脚本
线程组:保持默认
HTTP信息头管理器:名称content-type,值为application/json;charset=UTF-8
HTTP请求:协议http,服务器名称或IP为127.0.0.1,端口设置为8091,方法为post,路径/login,内容编码为utf-8,消息体数据设置如下
{
"username": "admin",
"password": "password"
}
运行脚本,查看结果树,在HTTP请求的响应数据中Response Body查看结果如下:
{"total":2,"data":[{"id":123,"name":"John Doe","email":"johndoe@example.com","phone":"123-456-7890","address":{"street":"123 Main St","city":"New York","state":"NY","zip":"10001"},"interests":["sports","music","travel"]},{"id":456,"name":"Jane Smith","email":"janesmith@example.com","phone":"987-654-3210","address":{"street":"456 Elm St","city":"Los Angeles","state":"CA","zip":"90001"},"interests":["reading","cooking","hiking"]}]}
HTTP请求的响应数据中Response Headers如下
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Content-Length: 433
Date: Thu, 18 Jul 2024 09:05:59 GMT
Keep-Alive: timeout=60
Connection: keep-alive
取样器结果查看可以得知如下内容
Data type (“text”|“bin”|“”): text
Response code: 200
Response message:
HTTPSampleResult fields:
ContentType: application/json;charset=UTF-8
DataEncoding: UTF-8
情况1:测试字段
响应文本
响应断言:测试字段选择响应文本,模式匹配规则选择包含,如上述返回消息内容可知有total字段,所以测试模式中添加输入total字符
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
响应代码
响应断言:测试字段选择响应代码,模式匹配规则选择包含,如上述返回消息头可知响应代码为200,所以测试模式中添加输入200
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
响应信息
响应断言:测试字段选择响应信息,模式匹配规则选择包含,如上述取样器结果可知响应信息Response message为null,模式匹配规则勾选否
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
响应头
响应断言:测试字段选择响应信息,模式匹配规则选择包含,如上述返回消息可知响应头中包含application/json;charset=UTF-8,所以测试模式中添加输入application/json;charset=UTF-8
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
请求头
响应断言:测试字段选择响应信息,模式匹配规则选择包含,如上述请求内容中可知请求头中包含Apache-HttpClient/4.5.7,所以测试模式中添加输入Apache-HttpClient/4.5.7
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
URL样本
响应断言:测试字段选择响应信息,模式匹配规则选择包含,如上述请求内容中可知请求体中包含http://127.0.0.1:8091/login,所以测试模式中添加输入http://127.0.0.1:8091/login
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
请求数据
响应断言:测试字段选择请求数据,模式匹配规则选择包含,如上述请求内容中可知请求体数据中包含
{
"username": "admin",
"password": "password"
}
所以测试模式中添加输入"username": “admin”
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
忽略状态
响应断言:勾选忽略状态
HTTP请求:编写一个不存在的接口,例如:/login1
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
但是具体看里面内容可以得到如下信息,在响应数据的Response Body中可以看到如下服务器返回错误
{"timestamp":"2024-07-19T02:21:12.237+00:00","status":404,"error":"Not Found","message":"","path":"/login1"}
Response Headers中可以看如下信息
HTTP/1.1 404
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 19 Jul 2024 02:21:12 GMT
Keep-Alive: timeout=60
Connection: keep-alive
情况2:模糊匹配规则
包含
响应断言:测试字段选择响应文本,模式匹配规则选择包含,如上述返回消息内容可知有total字段,所以测试模式中添加输入total字符
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
匹配
响应断言:测试字段选择响应文本,模式匹配规则选择匹配,如上述返回消息内容可知有total字段,所以测试模式中使用正则表达式.*total.*进行匹配,使用了.*来表示零个或多个任意字符,这样在匹配整个响应内容时会更灵活。
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
相等
响应断言:测试字段选择响应文本,模式匹配规则选择相等,如上述返回消息内容,所以测试模式中使用返回消息的所有内容进行断言。
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
字符串
响应断言:测试字段选择响应文本,模式匹配规则选择字符串,如上述返回消息内容可知有total字符串,所以测试模式中添加输入total字符串
运行结果,查看结果树中是否成功,http请求断言成功,不显示断言的结果
否
响应断言:测试字段选择响应文本,模式匹配规则选择字符串,如上述返回消息内容可知有total字符串,所以测试模式中添加输入total字符串,然后选择再勾选否
运行结果,查看结果树中是否成功,http请求断言失败,显示断言的结果
查看断言信息
Assertion error: false
Assertion failure: true
Assertion failure message: Test failed: text expected not to contain /total/
或者
响应断言:测试字段选择响应文本,模式匹配规则选择字符串,如上述返回消息内容可知有total,但是没有data1字符串,只有data,所以测试模式中添加第一个字符为total,,第二个字符为data1
运行结果,查看结果树中是否成功,http请求断言失败,显示断言的结果
查看断言信息
Assertion error: false
Assertion failure: true
Assertion failure message: Test failed: text expected to contain /data1/
然后我们再勾选模式匹配规则中的或者,再次运行脚本,http请求断言成功,不显示断言的结果
情况3:自定义失败的消息
响应断言:测试字段选择响应文本,模式匹配规则选择字符串,如上述返回消息内容可知有total字符串,所以测试模式中添加输入total字符串,然后选择再勾选否,自定义失败消息中添加内容“断言失败了”
运行结果,查看结果树中是否成功,http请求断言失败,显示断言的结果
查看断言信息
Assertion error: false
Assertion failure: true
Assertion failure message: 断言失败了
总结
响应断言是JMeter中进行结果验证的关键组件,通过精确控制验证条件,可以有效地评估系统行为是否符合预期。熟练掌握其配置与应用,对于提高测试效率和准确性至关重要。随着实践的深入,你将能更加灵活地运用各种匹配规则,以满足不同测试场景的需求。