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)同步更新。
This commit is contained in:
@@ -4,16 +4,21 @@
|
||||
|
||||
## 1. 选范围
|
||||
|
||||
未指定范围 → `--suite smoke`,风险上限 = `default_max_risk`。
|
||||
未指定范围 → `--tag smoke`,风险上限 = `default_max_risk`,`automation` 默认只跑 `automated`。
|
||||
|
||||
用户说分类、id、suite、风险上限时,原样传给 select:
|
||||
用户说分类、id、tag、风险上限时,原样传给 select:
|
||||
|
||||
```bash
|
||||
python3 <skill-dir>/scripts/catalog.py select --root <root> \
|
||||
[--category CAT] [--id ID]... [--suite smoke|full|slow] \
|
||||
[--max-risk <risk>] [--surface script|browser|mobile]
|
||||
[--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`)。这不是擅自扩大范围。
|
||||
@@ -23,8 +28,19 @@ python3 <skill-dir>/scripts/catalog.py select --root <root> \
|
||||
## 2. 运行前闸
|
||||
|
||||
- `HOST` 未设(环境变量 / `HX_TEST_HOST` / `local.yaml` 都没有):全部停,environment-fail。
|
||||
- 命中条的 `risk` 在 catalog `auth_env` 里有对应变量:变量不是 `true` 则该条 `skipped`。有 `gate` 时还要 `catalog.gates` 对应变量为 `true`。即使用户点了 id 也不执行。
|
||||
- 若 catalog 声明了 `status_probe`:先请求它。命中 `stop_if` → 整轮停,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
|
||||
|
||||
@@ -33,7 +49,7 @@ python3 <skill-dir>/scripts/catalog.py select --root <root> \
|
||||
- 尚未初始化:按 catalog `sessions.<name>.init` 做。`reuse: persist` 的先 `probe`,活着就附着。
|
||||
- 本轮已初始化:直接用,不要重开浏览器或模拟器。
|
||||
- `reuse: run`:整轮结束再关。`persist`:不关。
|
||||
- 中途 session 挂了:后续同 surface 标 environment-fail,不要标产品失败。
|
||||
- 中途 session 挂了:后续同 driver 标 environment-fail,不要标产品失败。
|
||||
|
||||
## 4. 执行
|
||||
|
||||
@@ -41,6 +57,12 @@ python3 <skill-dir>/scripts/catalog.py select --root <root> \
|
||||
|
||||
例外:当前条和下一条同属 `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`:
|
||||
@@ -59,9 +81,9 @@ python3 <skill-dir>/scripts/catalog.py run-script --root <root> --id <id>
|
||||
|
||||
## 5. 记录与报告
|
||||
|
||||
每条:`id, result, evidence, notes`。`result` 只能是 `pass` / `fail` / `environment-fail` / `skipped`。
|
||||
每条:`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 是否复用、逐条结果。立刻用同一快照生成 CSV,不要手改:
|
||||
写入 `.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>
|
||||
@@ -77,7 +99,7 @@ python3 <skill-dir>/scripts/generate_run_csv.py --root <root> --run <yaml>
|
||||
范围: …
|
||||
风险上限: …
|
||||
session: browser=复用|新开|未用;mobile=…
|
||||
计数: pass=N fail=N environment-fail=N skipped=N
|
||||
计数: pass=N fail=N environment-fail=N skipped=N not-run=N
|
||||
失败: id + 一句证据
|
||||
跳过: id + 原因
|
||||
快照: .pouch/tester/runs/<file>.yaml
|
||||
|
||||
Reference in New Issue
Block a user