feat(tester): add client journey testing standard
This commit is contained in:
@@ -40,6 +40,11 @@ catalog(整个测试集)
|
||||
| `how` | 怎么测:`steps` / `run` / `url` / `timeout` | test steps | 不是判定标准 |
|
||||
| `expected` | 怎么算过:`{kind, value}` 列表 | pytest `assert`;Robot `Should …` | 不是步骤 |
|
||||
| `run_together` | 必须成组执行的用例(有序、可选 continue_on_fail) | 场景组(scenario) | 不是 suite,不是 tag |
|
||||
| `client_suite` | 客户端用户旅程套件:`client-smoke` / `client-regression` / `safety` | mobile/browser E2E suite | 不是 `category`,也不是通用 tag;迁移期可读 `suite` 别名 |
|
||||
| `journey` | 用户目标、入口、操作、UI 断言、最终状态和失败继续策略 | Cucumber scenario / Robot task | 不是 API contract |
|
||||
| `fixture` | 旅程开始前声明的测试账号与隔离数据 | pytest fixture | 不是运行中临时猜出的数据 |
|
||||
| `cleanup` | 本轮数据的 teardown 契约;缺失会在 preflight 阻断 | pytest teardown / Robot teardown | 不是测试通过后的可选备注 |
|
||||
| `platform` | 旅程适用的 `android`/`ios` 平台列表 | device matrix | 不是 tester Agent binding;binding 仍在命令参数/运行环境 |
|
||||
|
||||
### 结果词
|
||||
|
||||
@@ -99,6 +104,19 @@ catalog(整个测试集)
|
||||
- 因此它是**分类级前置条件**:`catalog.status_probe` 是全局默认,`categories[].status_probe` 可覆盖(缺省继承 / `false` 关闭 / mapping 整体替换)。对应 pytest 的 session fixture、Robot 的 Suite Setup。
|
||||
- 命中或不可达只影响用它的分类;只有所有选中分类都被挡住,整轮结论才是 `environment-fail`。`select` 会按分类返回解析后的生效值,Agent 不要自己读 catalog 猜。
|
||||
|
||||
### 3.5 客户端套件和生命周期
|
||||
|
||||
客户端套件固定为:
|
||||
|
||||
- `client-smoke`:启动、正确账号登录和少量只读主路径,通常配 `tag=smoke`、`risk=readonly`。
|
||||
- `client-regression`:完整的普通用户旅程,可包含隔离环境中的 `mutating` 操作;不等于所有 full 用例。
|
||||
- `safety`:删除、权限边界、改密、停用或故障注入等危险旅程;必须显式选择和授权,不进入默认运行。
|
||||
|
||||
每条旅程按 `preflight → 启动 → 登录 → 旅程 → 断言 → 清理 → 报告` 执行。登录失败在
|
||||
客户端和正确测试账号都已就绪时记 `fail`;设备、产物、服务或 session 不可达才记
|
||||
`environment-fail`。fixture/cleanup 缺失是 contract block,不伪装成逐条结果。前置失败
|
||||
后的剩余条目是 `not-run`,主动排除仍是 `skipped`。
|
||||
|
||||
## 4. 不采用的词
|
||||
|
||||
| 词 | 不用它的原因 |
|
||||
|
||||
@@ -81,6 +81,15 @@ python3 <skill-dir>/scripts/catalog.py select --root <root> \
|
||||
[--binding android=tester.android] [--binding ios=tester.ios]
|
||||
```
|
||||
|
||||
客户端旅程还可按标准套件选择:
|
||||
|
||||
```bash
|
||||
python3 <skill-dir>/scripts/catalog.py select --root <root> --suite client-smoke
|
||||
```
|
||||
|
||||
`client-smoke`、`client-regression`、`safety` 是 `client_suite` 的固定值,不替换既有
|
||||
`tag=smoke|full|slow`。`safety` 不参与未指定范围的默认选择。
|
||||
|
||||
选中任一 `driver=mobile` 用例时,`--platform`、每个平台的 `--artifact` 和对应
|
||||
`tester` binding 是硬性参数;`catalog.py select` 会检查产物文件/下载地址和
|
||||
`.pouch/agent.yaml` 中的 binding。缺任何一项直接返回非零并打印 `preflight: blocked`,
|
||||
|
||||
@@ -14,6 +14,11 @@ runs/<run-id>.yaml 每次运行快照(执行源);run-id 必须唯一
|
||||
runs/*.csv 同一次运行的成绩单;generate_run_csv.py 从对应 yaml 生成
|
||||
```
|
||||
|
||||
客户端旅程在上述目录中仍使用同一套 cases/runs 和五态报告,不另造成绩单。启用旅程
|
||||
契约的用例声明 `client_suite`(兼容迁移期别名 `suite`);catalog 可用
|
||||
`client_suites` 显式列出三个标准套件:`client-smoke`、`client-regression`、`safety`。
|
||||
`category` 仍是文件/执行顺序容器,不被套件字段替代。
|
||||
|
||||
## catalog.yaml
|
||||
|
||||
| 字段 | 含义 |
|
||||
@@ -29,6 +34,7 @@ runs/*.csv 同一次运行的成绩单;generate_run_csv.py 从对
|
||||
| `id_pattern` | 用例 id 正则 |
|
||||
| `run_together` | 可选。成组执行:`[{ids: [TC-…, TC-…], continue_on_fail: true}]`。点到组内任一条,`select` 会按 `ids` 顺序把整组扩进命中列表。`continue_on_fail: true` 时组内前一条产品 fail 仍跑后一条(返回/收尾)。一个 id 只能属于一组。 |
|
||||
| `status_probe` | 可选。顶层默认值,一个**分类级前置条件**:`{url, stop_if: {字段: [命中值]}}`。运行前请求 `url`,响应命中任一 `stop_if` 条件即视为前置不满足。分类项可用同名键覆盖:缺省继承顶层、`false` 关闭、mapping 整体替换。命中或不可达只影响用它的分类,不是产品失败。业界对应 pytest 的 session fixture / Robot 的 Suite Setup。`select` 会按分类返回解析后的生效值,`url` 已用 `vars` 展开 |
|
||||
| `client_suites` | 可选的标准套件声明;出现时必须完整包含 `client-smoke`、`client-regression`、`safety`。缺省运行仍按 `tag` 兼容旧目录 |
|
||||
|
||||
`local.yaml` 与环境变量覆盖 `HOST` 和授权开关。模板中的 `HOST` 默认是
|
||||
`127.0.0.1`;远程目标必须显式覆盖。查找顺序:环境变量 > `local.yaml` >
|
||||
@@ -88,6 +94,50 @@ terminal;运行结束用 `orca terminal close --terminal <handle>` 关闭本
|
||||
| `teardown` | 否 | 跑完回退 |
|
||||
| `notes` | 否 | 备注 |
|
||||
|
||||
### 客户端旅程用例契约
|
||||
|
||||
声明 `client_suite` 后,以下字段都必须存在;`catalog.py validate` 和 `select` 使用同一
|
||||
套检查。契约缺失是 `preflight: blocked`,不生成逐条产品失败。
|
||||
|
||||
| 字段 | 必填 | 约束 |
|
||||
|------|------|------|
|
||||
| `client_suite` | 是 | `client-smoke`、`client-regression` 或 `safety`;安全套件必须显式选择,不属于默认 smoke/full |
|
||||
| `journey.goal` | 是 | 用户目标,不写接口目标 |
|
||||
| `journey.entry_state` | 是 | 启动/登录前的可观察入口状态 |
|
||||
| `journey.actions` | 是 | 非空用户操作列表;真实 App/browser 驱动从这里开始 |
|
||||
| `journey.assertions` | 是 | 非空可观察 UI 断言列表;最终业务状态可另由 `expected` 的 api-field/api-status 佐证 |
|
||||
| `journey.final_state` | 是 | 旅程完成后的业务状态 |
|
||||
| `journey.failure_policy` | 是 | `stop` 或 `continue`;默认不隐式吞掉前置失败 |
|
||||
| `fixture` | 是 | mapping,至少有 `account`;账号和数据由 app catalog 提供,skill 不写具体账号 |
|
||||
| `session` | 是 | 复用的 browser/mobile session 名,必须在 catalog.sessions 声明 |
|
||||
| `cleanup` | 是 | mapping,必须有非空 `steps`/`run`;只读旅程也要用 `required: false` + `reason` 显式说明无需清理 |
|
||||
| `platform` | 是 | `android`/`ios` 的字符串或列表,不能重复;平台差异只能进入执行适配层 |
|
||||
|
||||
一个最小形状如下(值是占位符,不是 app 规则):
|
||||
|
||||
```yaml
|
||||
client_suite: client-smoke
|
||||
platform: [android, ios]
|
||||
journey:
|
||||
goal: "用户完成一个可观察的客户端目标"
|
||||
entry_state: logged_out
|
||||
actions: ["启动客户端", "输入测试账号并登录", "完成目标操作"]
|
||||
assertions: ["看到目标页面", "看到成功提示"]
|
||||
final_state: "目标状态已保存"
|
||||
failure_policy: stop
|
||||
fixture:
|
||||
account: test-role
|
||||
data: []
|
||||
session: mobile
|
||||
cleanup:
|
||||
steps: ["删除本轮 run-id 创建的数据"]
|
||||
```
|
||||
|
||||
账号登录属于 session 初始化:正确测试账号登录失败是产品 `fail`;设备、产物或服务
|
||||
不可达才是 `environment-fail`。fixture/cleanup 缺失必须在启动、登录和任何旅程操作前
|
||||
阻断。旅程失败后,尚未轮到的用例记 `not-run`;风险、生命周期或明确范围排除记
|
||||
`skipped`。清理失败单独写入运行快照的 cleanup 证据,不改造为一个新的 result 值。
|
||||
|
||||
## how
|
||||
|
||||
按 `driver` 分派;`automation=manual` 时没有 `driver`,只有 `how.steps`(人工步骤)。
|
||||
|
||||
Reference in New Issue
Block a user