1
0

feat: 增强 expect 规则系统,支持多种 body 校验方法和操作符

- 新增 body 分组校验:contains、regex、json(JSONPath)、css(CSS选择器)、xpath
- 新增操作符系统:equals、contains、match、empty、exists、gte、lte、gt、lt
- 新增 headers 响应头校验
- 引入 cheerio、xpath、@xmldom/xmldom 依赖
- BREAKING: expect.bodyContains 迁移至 expect.body.contains
This commit is contained in:
2026-05-10 00:10:42 +08:00
parent 57d3a5cfb4
commit 599d973cbd
22 changed files with 923 additions and 80 deletions

View File

@@ -0,0 +1,117 @@
## Purpose
定义 HTTP 拨测中响应体校验方法集contains/regex/json/css/xpath、操作符系统和响应头校验的行为规范。
## Requirements
### Requirement: 响应体多种校验方法
系统 SHALL 支持对 HTTP 响应体进行五种可组合的校验方法contains子串、regex正则、jsonJSONPath、cssCSS 选择器、xpathXPath配置在 `expect.body` 分组下。
#### Scenario: contains 子串匹配
- **WHEN** 目标配置 `expect.body.contains: "healthy"`,且响应体包含 `"healthy"`
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: contains 不匹配
- **WHEN** 目标配置 `expect.body.contains: "healthy"`,且响应体不包含该文本
- **THEN** 系统 SHALL 判定 matched 为 false
#### Scenario: regex 正则匹配
- **WHEN** 目标配置 `expect.body.regex: '"status"\\s*:\\s*"ok"'`,且响应体匹配该正则
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: regex 不匹配
- **WHEN** 目标配置 `expect.body.regex: '"status"\\s*:\\s*"ok"'`,且响应体不匹配该正则
- **THEN** 系统 SHALL 判定 matched 为 false
#### Scenario: json JSONPath 等值匹配
- **WHEN** 目标配置 `expect.body.json: {"$.status": "ok"}`,且响应 JSON 中 `$.status` 值为 `"ok"`
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: json JSONPath 值不匹配
- **WHEN** 目标配置 `expect.body.json: {"$.status": "ok"}`,且响应 JSON 中 `$.status` 值为 `"error"`
- **THEN** 系统 SHALL 判定 matched 为 false
#### Scenario: json 解析失败
- **WHEN** 目标配置了 `expect.body.json` 但响应体不是合法 JSON
- **THEN** 系统 SHALL 判定 matched 为 false
#### Scenario: css 选择器匹配
- **WHEN** 目标配置 `expect.body.css: {"div#health": "OK"}`,且 HTML 中存在 `div#health` 元素文本为 `"OK"`
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: css 选择器匹配属性值
- **WHEN** 目标配置 css 规则带 `attr: "content"` 用于提取属性,且属性值匹配期望
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: css 选择器无匹配元素
- **WHEN** 目标配置了 css 选择器但 HTML 中无匹配元素
- **THEN** 系统 SHALL 判定 matched 为 false
#### Scenario: xpath 表达式匹配
- **WHEN** 目标配置 `expect.body.xpath: {"/root/status/text()": "ok"}`,且 XML 中 `/root/status` 节点文本为 `"ok"`
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: xpath 表达式无匹配节点
- **WHEN** 目标配置了 xpath 表达式但 XML 中无匹配节点
- **THEN** 系统 SHALL 判定 matched 为 false
### Requirement: 多种 body 校验方法 AND 组合
系统 SHALL 支持同时配置多种 body 校验方法,所有方法均通过时 matched 方为 true。
#### Scenario: 多种方法全部通过
- **WHEN** 目标同时配置 `body.contains``body.json``body.regex`,且全部通过
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: 多种方法任一失败
- **WHEN** 目标同时配置 `body.contains``body.json`,且 `body.contains` 不通过
- **THEN** 系统 SHALL 判定 matched 为 false且不再检查 `body.json`
### Requirement: 操作符系统
系统 SHALL 支持对 body 校验的提取值使用以下操作符进行比较equals默认等值、contains子串包含、match正则匹配、empty空值判断、exists存在性判断、gte/lte/gt/lt数值比较
#### Scenario: 标量值隐式 equals
- **WHEN** jsonPath 配置的期望值为标量(字符串/数字/布尔/null`$.status: ok`
- **THEN** 系统 SHALL 使用 equals 操作符,对提取值做严格相等比较
#### Scenario: 显式 contains 操作符
- **WHEN** 配置 `$.message: {contains: "success"}`,且提取值包含 `"success"`
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: 显式 match 操作符
- **WHEN** 配置 `$.version: {match: '\\d+\\.\\d+\\.\\d+'}`,且提取值匹配该正则
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: empty 操作符判断为空
- **WHEN** 配置 `$.items: {empty: true}`,且提取值为空数组 `[]`
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: empty 操作符判断非空
- **WHEN** 配置 `$.items: {empty: false}`,且提取值为 `[1, 2]`
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: exists 操作符判断存在
- **WHEN** 配置 `$.error: {exists: false}`,且 JSON 中不存在 `error` 字段
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: gte 数值比较
- **WHEN** 配置 `$.count: {gte: 10}`,且提取值为 `15`(数字)
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: gt/lt 数值比较
- **WHEN** 配置 `$.latency: {gt: 0, lt: 1000}`,且提取值为 `500`
- **THEN** 系统 SHALL 对同一字段进行多操作符复合比较,全部通过则 matched 为 true
### Requirement: 响应头校验
系统 SHALL 支持通过 `expect.headers` 配置对响应头进行键值对校验。
#### Scenario: 响应头匹配
- **WHEN** 目标配置 `expect.headers: {"Content-Type": "application/json"}`,且响应包含该 header 且值匹配
- **THEN** 系统 SHALL 判定 matched 为 true
#### Scenario: 响应头不匹配
- **WHEN** 目标配置 `expect.headers: {"Content-Type": "application/json"}`,且响应 header 值为 `"text/html"`
- **THEN** 系统 SHALL 判定 matched 为 false
#### Scenario: 响应头缺失
- **WHEN** 目标配置了某个 header 但响应中不存在该 header
- **THEN** 系统 SHALL 判定 matched 为 false