Files
.pouch/skills/tester/references/run.md
T
laily cc9af04a40 tester v2: 术语对齐 pytest/JUnit/Robot,补齐 automation 与 not-run
字段改名(每项取舍的理由见新增的 references/concepts.md):
- 用例 status -> lifecycle, suite -> tag, surface -> driver,
  cleanup -> teardown, skip_unless -> assume;删除 requires
- risk 取值 safe/act/harm -> readonly/mutating/destructive(单调三级,
  与 gate 正交)
- catalog auth_env -> authorize;授权变量统一为
  AUTHORIZE_MUTATING / AUTHORIZE_DESTRUCTIVE

新增用例字段 automation(automated/assisted/manual),默认 automated,
并在 validate 里机器校验:manual 禁用 driver 与 how.run 且必须有
how.steps;assisted 至少一步以 [人工] 开头。select 新增 --automation。

结果词新增 not-run,区分「主动不跑」(skipped:retired/pending/超风险
上限/未授权/assume 不成立)与「没轮到」(失败即停后、被分类前置挡住整组、
需人工而无人值守)。

status_probe 定为分类级前置条件:catalog 顶层为默认,categories[] 同名键
覆盖(缺省继承 / false 关闭 / mapping 整体替换)。select 按分类返回生效值,
并把 probe.url 用 vars 展开(solve Agent 无法自行解析 ${VAR} 的问题),
同批返回 vars 供 how 里的 ${...} 替换。

新增 references/concepts.md:术语表(每词一句唯一定义 + 业界锚点 +
反例)、v1->v2 映射、以及 risk/automation/not-run/status_probe 的设计理由。
其余文档(SKILL/README/schema/levels/run/maintain)与三个脚本(catalog、
generate_cases_csv、generate_run_csv)同步更新。
2026-09-16 23:07:08 +08:00

109 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# tester 运行
只在用户要跑测试时读本文件。
## 1. 选范围
未指定范围 → `--tag smoke`,风险上限 = `default_max_risk`,`automation` 默认只跑 `automated`。
用户说分类、id、tag、风险上限时,原样传给 select:
```bash
python3 <skill-dir>/scripts/catalog.py select --root <root> \
[--category CAT] [--id ID]... [--tag smoke|full|slow] \
[--max-risk <risk>] [--driver script|browser|mobile] \
[--automation automated|assisted|manual|any]
```
`--automation` 默认 `automated`(需人工的条目会被跳过,并在 JSON `skipped` 里说明);用户明确要求现场配合时用 `assisted`,`any` 表示不按人工参与度筛。
`select` 的 JSON 字段:`max_risk` / `automation` / `count` / `vars`(已展开的变量,用来替换 `how` 里的 `${…}`)/ `skipped` / `run_together` / `status_probe`(按分类,`url` 已展开)/ `cases`。
`select` 已排除 `retired` 和风险高于上限的条目(后者若用户点了具体 id,会在 JSON 的 `skipped` 里说明,不执行)。
若 catalog 有 `run_together`,命中组内任一条就把整组按 `ids` 顺序扩进列表(JSON 带 `run_together`)。这不是擅自扩大范围。
无命中:停下说明筛选条件,不要扩大范围。
## 2. 运行前闸
- `HOST` 未设(环境变量 / `HX_TEST_HOST` / `local.yaml` 都没有):全部停,environment-fail。
- 命中条的 `risk` 在 catalog `authorize` 里有对应变量:变量不是 `true` 则该条 `skipped`。有 `gate` 时还要 `catalog.gates` 对应变量为 `true`;`assume` 不成立同样 `skipped`。即使用户点了 id 也不执行。
- 授权/假设不成立是**主动不跑**(`skipped`),不是 `not-run`:这是我们决定不跑,不是没轮到。
- `status_probe` 是**分类级前置条件**(业界对应 pytest 的 session fixture / Robot 的 Suite Setup)。用 `select` 返回的 `status_probe` 解析生效值,不要自己读 catalog 猜。返回的 `probe.url` 已用 `vars` 展开,直接请求即可;`select` 同批返回 `vars`:
| `categories[].status_probe` | 生效探测 |
|------------------------------|----------|
| 未声明 | 继承顶层 `catalog.status_probe`(`source: global`)|
| `false` | 该分类不做闸(`source: disabled`)|
| mapping | 整体覆盖顶层,不合并(`source: category`)|
- 同一生效探测一次运行只请求一次,结果复用。
- 探测不可达:用它的分类标 environment-fail,其余分类照跑。
- 命中 `stop_if`:把用它的分类标 environment-fail 并记 `observed` 值,其余分类照跑;所有选中分类都被挡住时,整轮结论才是 environment-fail。
## 3. Session
看命中条用到的 `session` 键:
- 尚未初始化:按 catalog `sessions.<name>.init` 做。`reuse: persist` 的先 `probe`,活着就附着。
- 本轮已初始化:直接用,不要重开浏览器或模拟器。
- `reuse: run`:整轮结束再关。`persist`:不关。
- 中途 session 挂了:后续同 driver 标 environment-fail,不要标产品失败。
## 4. 执行
按 select 返回的顺序,一条一条来。select 按 `catalog.yaml` 的 `categories` 顺序,同一分类内按该 yaml 列表顺序(不是文件名字母序)。默认失败即停(产品 `fail` 或探测到的不安全状态)。用户说继续 / keep-going 才往后跑。
例外:当前条和下一条同属 `run_together` 且该组 `continue_on_fail: true` 时,前一条产品 `fail` 仍跑后一条。`environment-fail` 仍整轮停。
**automation**
- `automated`:Agent 端到端执行。
- `assisted`:照常驱动,但遇到以 `[人工]` 开头的 `how.steps` 时停下,请现场人员执行并回报,确认后再继续。无人值守时该条记 `not-run`。
- `manual`:没有 `driver`,`run-script` 会直接返回 `not-run`。只能由人执行、回报结果,Agent 负责记录。
**script**
有 `how.run`:
```bash
python3 <skill-dir>/scripts/catalog.py run-script --root <root> --id <id>
```
`run-script` 只跑命令,返回 `executed` + stdout/exit(或 skipped / environment-fail)。**pass/fail 仍由 Agent 对照 `expected` 判定**,不要把 curl 退出码 0 当成产品通过。
没有 `run`:按 `how.steps` 做,证据对照 `expected`。不要发明 steps 里没有的调用。
**browser / mobile**
挂到已有 session,执行 `how.steps`,对照 `expected`。必须留下可见文本、URL 或交互证据。
## 5. 记录与报告
每条:`id, result, evidence, notes`。`result` 只能是 `pass` / `fail` / `environment-fail` / `skipped` / `not-run`。`skipped` 是主动不跑(retired / pending / 超风险上限 / 未授权 / `assume` 不成立),`not-run` 是没轮到(失败即停后剩下的 / 被前置整组挡住的 / 需人工而无人值守的)。
写入 `.pouch/tester/runs/<UTC时间>-<范围>.yaml`,包含筛选条件、HOST 是否已设(可以写 HOST 值)、session 是否复用、每个分类的 `status_probe` 生效值与观测结果(`source` / `disabled` 原因 / `hit` / `observed`)、逐条结果。立刻用同一快照生成 CSV,不要手改:
```bash
python3 <skill-dir>/scripts/generate_run_csv.py --root <root> --run <yaml>
```
这会写出 `.pouch/tester/runs/<UTC时间>-<范围>.csv`(`executed=yes|no`),并刷新 `cases.csv` 的 `last_result` / `last_executed` 列。对话里两个路径都报。
对话报告:
```text
## tester 运行:完成 | 部分完成 | 阻塞
范围: …
风险上限: …
session: browser=复用|新开|未用;mobile=…
计数: pass=N fail=N environment-fail=N skipped=N not-run=N
失败: id + 一句证据
跳过: id + 原因
快照: .pouch/tester/runs/<file>.yaml
成绩单: .pouch/tester/runs/<file>.csv
下一步: 一句话
```