@wwkit/harness 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +6 -6
  2. package/agents/work.md +89 -696
  3. package/commands/pytest.md +11 -0
  4. package/package.json +1 -1
  5. package/readme/development.md +1 -1
  6. package/skills/extract/SKILL.md +90 -28
  7. package/{agents/pyit.md → skills/pytest/SKILL.md} +223 -64
  8. package/skills/pytest-env-ensure/references/config.md +2 -2
  9. package/skills/pytest-sample/SKILL.md +3 -3
  10. package/skills/read-docs/references/superpowers/comparison.md +1 -1
  11. package/skills/read-docs/references/superpowers/index.md +1 -1
  12. package/skills/revise/SKILL.md +86 -25
  13. package/skills/work-dispatch/SKILL.md +78 -0
  14. package/skills/work-dispatch/references/dispatch-prompt.md +87 -0
  15. package/skills/work-dispatch/references/prepare.md +25 -0
  16. package/skills/work-dispatch/references/report-handling.md +38 -0
  17. package/skills/work-finalize/SKILL.md +83 -0
  18. package/skills/work-finalize/references/acceptance.md +19 -0
  19. package/skills/work-finalize/references/final-review.md +53 -0
  20. package/skills/work-finalize/references/handover.md +28 -0
  21. package/skills/work-ledger/SKILL.md +73 -0
  22. package/skills/work-ledger/references/bootstrap.md +28 -0
  23. package/skills/work-ledger/references/layout.md +25 -0
  24. package/skills/work-ledger/references/ledger-format.md +57 -0
  25. package/skills/work-plan/SKILL.md +81 -0
  26. package/skills/work-plan/references/plan-file.md +29 -0
  27. package/skills/work-plan/references/self-review.md +18 -0
  28. package/skills/work-plan/references/split-rules.md +23 -0
  29. package/skills/work-plan/references/task-fields.md +44 -0
  30. package/skills/work-recovery/SKILL.md +80 -0
  31. package/skills/work-recovery/references/budget.md +40 -0
  32. package/skills/work-recovery/references/replan.md +21 -0
  33. package/skills/work-recovery/references/rollback.md +20 -0
  34. package/skills/work-review/SKILL.md +95 -0
  35. package/skills/work-review/references/breaker.md +26 -0
  36. package/skills/work-review/references/fix-loop.md +118 -0
  37. package/skills/work-review/references/review-package.md +24 -0
  38. package/skills/work-review/references/reviewer-prompt.md +77 -0
  39. package/skills/work-review/references/verdict-handling.md +25 -0
  40. package/agents/extract.md +0 -26
  41. package/agents/pyut.md +0 -347
  42. package/agents/revise.md +0 -28
  43. package/commands/pyit.md +0 -6
  44. package/commands/pyut.md +0 -6
@@ -1,47 +1,121 @@
1
1
  ---
2
+ name: pytest
2
3
  description: |
3
- Python 集成测试指挥官。协调模块适用性评估→环境检查→覆盖率分析→用例创建→测试执行→用例修复的完整流程。
4
- 最少 Mock,优先真实调用,目标覆盖率 70%。适用于 uv 管理的 Python 项目的集成测试自动化。
5
- 触发词:pyit、集成测试、integration test、集成测试覆盖率。
6
- mode: subagent
4
+ 自包含 Python 测试 skill:合并原 pyut(单元测试)和 pyit(集成测试)。
5
+ 通过 test_type=unit|integration 区分:unit 全 Mock 目标覆盖率 90%,integration 最少 Mock 目标覆盖率 70%。
6
+ 协调适用性评估→环境检查→覆盖率分析→用例创建→测试执行→用例修复的完整流程,内外两层 loop。
7
+ 调用方直接传原始任务消息,skill 自解析自包含。内部用 todowrite 管理 7 步。适用于 uv 管理的 Python 项目。
8
+ license: MIT
9
+ metadata:
10
+ workflow: sequential
7
11
  ---
8
12
 
9
- 你是 Python 集成测试指挥官(pyit)。你负责协调一套完整的集成测试流程,确保目标模块的场景覆盖率和质量达到标准。
13
+ # pytest 技能
10
14
 
11
- ## 你的职责
15
+ ## 核心约束(最高优先级)
12
16
 
13
- 1. 接收用户输入的源码路径和可选测试目录
14
- 2. 调用 pytest-suitability-check 评估模块适用性,得到可测试类清单
15
- 3. 调用 pytest-env-ensure 检查环境并加载配置
16
- 4. 协调覆盖率分析 → 用例创建 → 测试执行 → 用例修复的内外两层 loop
17
- 5. 管理 loop 次数和退出条件
18
- 6. 输出最终测试质量报告并写入 `{report_dir}/test_report.md`
17
+ - **MUST**:收到任务消息后,先 todowrite 落单 7 步,再逐步执行。
18
+ - **MUST**:每步完成立即 todowrite 勾单。
19
+ - **MUST**:test_type 只能是 unit 或 integration,其他值报错退出。
20
+ - **禁止**:混合测试类型(unit 不混合 integration,反之亦然)。
21
+ - **禁止**:修改 conftest.py(除非直接导致失败)。
19
22
 
20
- ## 配置参数
23
+ ## 第一步硬指令(自检)
24
+
25
+ 解析入参前,强制自检:
26
+ > 我是否已用 todowrite 落单 7 步?
27
+ > - 未落单 → 立即 todowrite 创建清单。
28
+ > - 已落单 → 继续。
29
+
30
+ ## 配置表(按 test_type 分支)
31
+
32
+ | 维度 | unit | integration |
33
+ |------|------|-------------|
34
+ | coverage_threshold | 90 | 70 |
35
+ | mock_strategy | full(全部 Mock 外部依赖) | minimal(最少 Mock,优先真实调用) |
36
+ | test_dir 前缀 | tests/unit/ | tests/integration/ |
37
+ | 适用性过滤 | 不过滤,所有类都适合 | 仅外部依赖类(Service/Integration Point/External Adapter),过滤 Pure Utility / Data Model |
38
+ | 环境补充检查 | 无 | DB连接 / 外部服务连通性 / 测试数据目录(非阻断式警告) |
39
+ | 环境依赖 | pytest, pytest-cov | pytest, pytest-cov, pytest-timeout |
40
+ | pytest marker | unit | integration |
41
+ | 覆盖率权重 | 行30 / 分支30 / 函数20 | 行20 / 分支20 / 函数10 |
42
+ | 覆盖率阈值(行/分支/函数) | 90% / 70% / 90% | 70% / 50% / 70% |
43
+ | 质量维度 | 断言完整性5 / 异常路径5 / 边界值5 / 命名规范5 | 场景完整性15 / 数据流验证10 / 断言完整性10 / fixture使用10 / 命名规范5 |
44
+ | 特殊规则 | 不修改 conftest;不混合集成测试 | 按业务场景组织用例;不混合单元测试 |
45
+ | 报告标题 | pytest unit 测试质量报告 | pytest integration 测试质量报告 |
46
+ | 退出达标 | score ≥ 90 | score ≥ 70 |
47
+
48
+ 通用配置(两种 test_type 共享):
21
49
 
22
- - test_type: **integration**
23
- - coverage_threshold: **70**(来自 config)
24
50
  - outer_max: **3**(外层 loop 最大轮次)
25
51
  - inner_max: **3**(内层 loop 最大轮次)
26
- - mock_strategy: **minimal**(最少 Mock,优先真实调用)
52
+ - report 路径:`{test_dir}/reports/{YYYYMMDD_HHMMSS}/test_report.md`
53
+
54
+ ## 输入参数(自包含)
55
+
56
+ 入参为调用方传入的**原始任务消息**,可能是以下任一形态:
57
+
58
+ - **JSON 对象**:`{test_type, source, test_dir}`,直接取字段值。
59
+ - **key=value**:`test_type=unit, source=src/mymodule`,按 `,` 和 `=` 拆分为字段。
60
+ - **纯文本 prose**:含 "集成/integration" → integration;含 "单元/unit" → unit;默认 unit。`source` 从文本中出现的路径推断。
61
+ - **命令风格**:`unit src/mymodule` 或 `integration src/mymodule tests/integration/mymodule`,第一段为 test_type,第二段为 source,第三段(可选)为 test_dir。
62
+
63
+ 字段清单:
64
+
65
+ | 字段 | 类型 | 必填 | 说明 |
66
+ |------|------|------|------|
67
+ | test_type | string | 是 | `unit` 或 `integration`,其他值报错退出 |
68
+ | source | string | 是 | 源码包目录或 .py 文件路径 |
69
+ | test_dir | string | 否 | 测试目录;未指定时按 `tests/{test_type}/{归一化路径}/` 自动推导 |
70
+
71
+ **必填校验**:若无法解析出 `test_type` 或 `source`,将错误信息输出到 stderr 并结束,**禁止**继续执行。
72
+
73
+ **test_type 校验**:解析后若 `test_type` 不在 `{unit, integration}` 中,输出 "test_type 只能是 unit 或 integration,得到: {value}" 并结束。
74
+
75
+ ## 输出
76
+
77
+ - 流程结束后将最终报告写入 `{report_dir}/test_report.md`,同时在 chat 中输出报告摘要。
78
+ - 源码 Bug 汇总(若有)写入 `{report_dir}/bug_list.md`。
79
+ - 中间产物(临时评分文件等)写入 `report_dir`,不污染源码目录。
27
80
 
28
81
  ## 工作流程
29
82
 
83
+ ### 阶段 0:todowrite 落单
84
+
85
+ 收到任务消息后,先用 `todowrite` 创建 7 步清单(status=pending):
86
+
87
+ 1. 入参校验与目录映射(test_type + source + test_dir)
88
+ 2. 模块适用性评估
89
+ 3. 环境检查(+ integration 补充检查)
90
+ 4. 覆盖率分析(外层 loop)
91
+ 5. 用例创建
92
+ 6. 测试执行
93
+ 7. 用例修复(内层 loop)
94
+
95
+ 每步完成立即 todowrite 勾单(status=completed)。
96
+
30
97
  ### Step 1:入参校验与目录映射
31
98
 
32
- 接收两个参数:`$1`(源码路径,必填)、`$2`(测试目录,可选)。
99
+ 将第 1 步标记为 in_progress,按"输入参数"小节解析原始任务消息,得到 `test_type`、`source`、`test_dir`。
33
100
 
34
- #### 参数1校验(源码路径)
101
+ #### test_type 校验
35
102
 
36
103
  | 检查项 | 失败提示 |
37
104
  |--------|---------|
38
- | 为空 | "请提供源码路径,如 /pyit src/mymodule" |
105
+ | 为空 | "请提供 test_type(unit 或 integration)" |
106
+ | 非 unit/integration | "test_type 只能是 unit 或 integration,得到: {value}" |
107
+
108
+ #### 参数 source 校验(源码路径)
109
+
110
+ | 检查项 | 失败提示 |
111
+ |--------|---------|
112
+ | 为空 | "请提供源码路径,如 pytest src/mymodule(test_type=unit)" |
39
113
  | 不存在 | "路径不存在: {path}" |
40
114
  | 是 .py 文件 | 直接使用该文件作为 target(单文件测试模式) |
41
115
  | 是非 .py 文件 | "非 Python 文件: {path}" |
42
116
  | 是目录但无 .py 文件 | "目录下无 Python 文件: {path}" |
43
117
 
44
- #### 参数2校验(测试目录,可选)
118
+ #### 参数 test_dir 校验(可选)
45
119
 
46
120
  | 条件 | 行为 |
47
121
  |------|------|
@@ -50,13 +124,20 @@ mode: subagent
50
124
  | 指定但非目录 | "测试路径不是目录: {path}" |
51
125
  | 合法 | 直接使用,跳过映射推导 |
52
126
 
53
- #### 目录映射规则($2 未指定时自动推导)
127
+ #### 目录映射规则(test_dir 未指定时自动推导)
54
128
 
55
- 按 `references/config.md` 的"目录映射算法"执行,其中 `test_type = integration`。
129
+ 核心规则:`test_dir = tests/{test_type}/{归一化路径}/`,归一化仅去除 `src/` 前缀,保留包名。
56
130
 
57
- 核心规则:`test_dir = tests/integration/{归一化路径}/`,归一化仅去除 `src/` 前缀,保留包名。
131
+ **映射示例(unit)**:
58
132
 
59
- **映射示例**:
133
+ | 源码路径 | 归一化 | 自动推导 test_dir |
134
+ |---------|--------|------------------|
135
+ | `src/pytest-sample` | `pytest-sample` | `tests/unit/pytest-sample/` |
136
+ | `src/mypackage/sub` | `mypackage/sub` | `tests/unit/mypackage/sub/` |
137
+ | `src/mypackage/MyService.py` | `mypackage` | `tests/unit/mypackage/` |
138
+ | `mypackage/sub`(flat layout) | `mypackage/sub` | `tests/unit/mypackage/sub/` |
139
+
140
+ **映射示例(integration)**:
60
141
 
61
142
  | 源码路径 | 归一化 | 自动推导 test_dir |
62
143
  |---------|--------|------------------|
@@ -69,10 +150,11 @@ mode: subagent
69
150
  #### 产出
70
151
 
71
152
  Step 1 结束后,确定以下变量,传递给后续所有 skill:
153
+
72
154
  - `target`:源码路径
73
155
  - `test_dir`:测试目录路径
74
156
  - `report_dir`:报告输出目录,格式为 `{test_dir}/reports/{YYYYMMDD_HHMMSS}/`
75
- - `test_type`:integration
157
+ - `test_type`:unit 或 integration
76
158
  - `flow_start_time`:流程开始时间戳(执行 `date +%s` 获取)
77
159
 
78
160
  **报告目录规则**:
@@ -81,33 +163,48 @@ Step 1 结束后,确定以下变量,传递给后续所有 skill:
81
163
 
82
164
  **退出条件**:参数校验失败 → 直接退出,不进入后续流程。
83
165
 
166
+ 完成后 todowrite 勾单第 1 步。
167
+
84
168
  ### Step 2:模块适用性评估
85
169
 
86
170
  调用 **pytest-suitability-check** 技能,传入参数:
171
+
87
172
  - target: 源码包目录路径
88
- - test_type: integration
173
+ - test_type: 当前 test_type
174
+
175
+ **分支:test_type == unit**
176
+
177
+ UT 理论上对所有类都适合,此步骤主要提供分类信息,**不做过滤**。所有类都进入 `testable_classes`。
178
+
179
+ **分支:test_type == integration**
89
180
 
90
181
  IT 仅适合有外部依赖的类(Service Class / Integration Point / External Adapter),Pure Utility 和 Data Model 类将被过滤。
91
182
 
92
183
  **产出**:
184
+
93
185
  - `testable_classes`:可测试类清单(文件路径 + 类名 + 分类),传递给 Step 5
94
186
 
95
187
  **退出条件**:
188
+
96
189
  - 可测试清单非空 → 继续 Step 3,保存 `testable_classes` 供 Step 5 使用
97
190
  - 可测试清单为空 → 根据原因提示并终止:
98
191
  - 无 .py 文件 → "目录下无 Python 文件"
99
192
  - 有 .py 文件但无类定义 → "未发现类定义,仅有函数/模块级代码"
100
- - 有类定义但全部被过滤(无外部依赖) → "未发现适合集成测试的类(需有外部依赖),建议改用 /pyut"
193
+ - 有类定义但全部被过滤(test_type=integration 无外部依赖) → "未发现适合集成测试的类(需有外部依赖),建议改用 test_type=unit"
194
+ - 有类定义但全部被跳过(test_type=unit) → "可测试类被全部跳过: {跳过原因}"
195
+
196
+ 完成后 todowrite 勾单第 2 步。
101
197
 
102
198
  ### Step 3:环境检查
103
199
 
104
200
  调用 **pytest-env-ensure** 技能:
201
+
105
202
  - 检查是否为 uv 项目
106
- - 检查并安装依赖(pytest, pytest-cov, pytest-timeout)
107
- - 检查 pytest marker 注册(unit, integration)
203
+ - 检查并安装依赖(test_type=unit: pytest, pytest-cov;test_type=integration: pytest, pytest-cov, pytest-timeout)
204
+ - test_type=integration 时:检查 pytest marker 注册(unit, integration)
108
205
  - 加载配置清单(references/config.md)
109
206
 
110
- **集成测试环境补充检查**(env-ensure 之后执行):
207
+ **分支:test_type == integration 的环境补充检查**(env-ensure 之后执行)
111
208
 
112
209
  | 检查项 | 方法 | 失败处理 |
113
210
  |--------|------|---------|
@@ -115,9 +212,18 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
115
212
  | 外部服务连通性 | ping 源码中引用的外部服务地址 | 记录警告,提示对应服务不可用 |
116
213
  | 测试数据目录 | 检查 test_dir 是否存在,若存在则检查 fixtures/ 子目录 | test_dir 不存在则提示首轮会自动创建;fixtures/ 不存在则提示 case-create 会自动创建 |
117
214
 
118
- > 集成测试环境检查为**非阻断式**:记录警告但不退出流程。集成测试可能依赖运行时环境,agent 无法自动修复,仅提示用户。
215
+ > 集成测试环境检查为**非阻断式**:记录警告但不退出流程。集成测试可能依赖运行时环境,skill 无法自动修复,仅提示用户。
119
216
 
120
- **退出条件**:env-ensure 失败 → 直接退出。集成环境警告 → 继续流程。
217
+ **分支:test_type == unit**
218
+
219
+ 无补充检查。env-ensure 失败即退出。
220
+
221
+ **退出条件**:
222
+
223
+ - env-ensure 失败 → 直接退出,提示用户。
224
+ - test_type=integration 的环境警告 → 继续流程(非阻断)。
225
+
226
+ 完成后 todowrite 勾单第 3 步。
121
227
 
122
228
  ### Step 4:覆盖率分析(外层 loop 开始)
123
229
 
@@ -137,7 +243,7 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
137
243
  - target: 用户指定的模块路径
138
244
  - test_dir: 从 Step 1 确定的测试目录路径
139
245
  - report_dir: 从 Step 1 确定的报告输出目录
140
- - test_type: integration
246
+ - test_type: 当前 test_type(unit 或 integration)
141
247
  - config: 从 Step 3 获得的配置
142
248
  - previous_score: round_start_score 值(首轮不传,由 coverage-analyze 自行处理 null)
143
249
 
@@ -147,17 +253,21 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
147
253
  1. **轮首调用**(round 2+,或 round 1 有已有测试时):用于识别未覆盖区域,供 Step 5 case-create 使用。将得到的 score 保存到 `round_start_score`,作为本轮改进比较的基准。**此调用不检查退出条件**。
148
254
  2. **轮尾调用**(所有 round):在 case-create → execute → fix 完成后重新评分,与 `round_start_score` 比较判断是否有改进。**此调用检查所有退出条件**。
149
255
 
256
+ 设 `threshold = config[test_type].coverage_threshold`(unit=90, integration=70)。
257
+
150
258
  **退出条件**(仅在轮尾调用时检查):
151
- - score ≥ 70 → 输出最终报告,流程结束
259
+ - score ≥ threshold → 输出最终报告,流程结束
152
260
  - score ≤ round_start_score → 输出"无改进"报告,流程结束
153
- - score < 70 且 outer_round < 3 → 进入下一轮外层 loop(outer_round + 1)
154
- - score < 70 且 outer_round = 3 → 输出"超限"报告,流程结束
261
+ - score < threshold 且 outer_round < 3 → 进入下一轮外层 loop(outer_round + 1)
262
+ - score < threshold 且 outer_round = 3 → 输出"超限"报告,流程结束
155
263
 
156
264
  **轮首调用**(round 2+,或 round 1 有已有测试时):
157
265
  - 获取 `uncovered_areas` 和 `score`,将 `score` 保存到 `round_start_score`(供轮尾比较)
158
266
  - 不检查退出条件
159
267
  - 直接进入 Step 5
160
268
 
269
+ 完成后 todowrite 勾单第 4 步。
270
+
161
271
  ### Step 5:用例创建
162
272
 
163
273
  调用 **pytest-case-create** 技能,传入参数:
@@ -165,22 +275,24 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
165
275
  - testable_classes: 从 Step 2 获得的可测试类清单
166
276
  - target: 目标模块路径
167
277
  - test_dir: 从 Step 1 确定的测试目录路径
168
- - test_type: integration
278
+ - test_type: 当前 test_type
169
279
  - config: 配置对象
170
280
 
171
- **注意**:mock_strategy=minimal,优先真实调用,仅 Mock 不可控的外部服务。该技能直接使用传入的 test_dir 扫描已有测试,增量追加不覆盖。
281
+ **注意**:mock_strategy = config[test_type].mock_strategy(unit=full 全部 Mock,integration=minimal 最少 Mock)。该技能直接使用传入的 test_dir 扫描已有测试,增量追加不覆盖。
172
282
 
173
283
  **退出条件**:
174
284
  - 新增用例 > 0 → 进入 Step 6
175
285
  - 新增用例 = 0 → 跳过 Step 6+7,直接回到 Step 4 轮尾评分(轮尾 score 将等于 round_start_score,触发"无改进"退出)
176
286
  - uncovered_areas 为空 → 跳过 Step 6+7,直接回到 Step 4 轮尾评分
177
287
 
288
+ 完成后 todowrite 勾单第 5 步。
289
+
178
290
  ### Step 6:测试执行
179
291
 
180
292
  调用 **pytest-execute** 技能,传入参数:
181
293
  - target: 目标模块路径
182
294
  - test_dir: 从 Step 1 确定的测试目录路径
183
- - test_type: integration
295
+ - test_type: 当前 test_type
184
296
  - config: 配置对象
185
297
  - test_files: Step 5 新创建的测试文件(可选)
186
298
 
@@ -188,13 +300,15 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
188
300
  - 全部通过 → 回到 Step 4 轮尾评分(当前轮次,outer_round 递增在轮尾评分后发生)
189
301
  - 有失败 → 进入 Step 7
190
302
 
303
+ 完成后 todowrite 勾单第 6 步。
304
+
191
305
  ### Step 7:用例修复(内层 loop)
192
306
 
193
307
  调用 **pytest-case-fix** 技能,传入参数:
194
308
  - failed_tests: 从 Step 6 获得的失败用例清单
195
309
  - test_dir: 从 Step 1 确定的测试目录路径
196
310
  - report_dir: 从 Step 1 确定的报告输出目录
197
- - test_type: integration
311
+ - test_type: 当前 test_type
198
312
  - config: 配置对象
199
313
 
200
314
  **退出条件**:
@@ -202,10 +316,14 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
202
316
  - 无修复(全部标记人工处理)→ 内层 loop 退出,回到 Step 4 轮尾评分
203
317
  - inner_round ≥ 3 → 内层 loop 退出,回到 Step 4 轮尾评分
204
318
 
205
- **源码修改注意**:如果 case-fix 修改了源码文件,回到外层 loop 时 `testable_classes`(Step 2 产出)可能已过期。agent 应在状态快照中标记 `[STATE] source_modified=true`,并在外层 loop round 2+ 时提示"源码已修改,适用性清单可能过期"。
319
+ **源码修改注意**:如果 case-fix 修改了源码文件,回到外层 loop 时 `testable_classes`(Step 2 产出)可能已过期。应在状态快照中标记 `[STATE] source_modified=true`,并在外层 loop round 2+ 时提示"源码已修改,适用性清单可能过期"。
320
+
321
+ 完成后 todowrite 勾单第 7 步。
206
322
 
207
323
  ## Loop 控制状态机
208
324
 
325
+ 设 `threshold = config[test_type].coverage_threshold`(unit=90, integration=70)。
326
+
209
327
  ```
210
328
  外层 loop (max 3):
211
329
  round 1: [首轮跳过 coverage-analyze] → case-create → execute → [fix → execute] → coverage-analyze(轮尾评分)
@@ -219,10 +337,10 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
219
337
  退出条件只在轮尾 coverage-analyze(case-create→execute→fix 完成后)检查。
220
338
 
221
339
  外层退出条件(仅轮尾 coverage-analyze 检查):
222
- - score ≥ 70 → 达标退出
340
+ - score ≥ threshold → 达标退出
223
341
  - score ≤ round_start_score → 无改进退出
224
- - score < 70 且 outer_round = 3 → 超限退出
225
- - score < 70 且 outer_round < 3 → outer_round + 1,进入下一轮
342
+ - score < threshold 且 outer_round = 3 → 超限退出
343
+ - score < threshold 且 outer_round < 3 → outer_round + 1,进入下一轮
226
344
 
227
345
  内层 loop (max 3):
228
346
  fix → execute → fix → execute → fix → execute
@@ -245,7 +363,7 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
245
363
 
246
364
  | 变量 | 初始值 | 更新时机 |
247
365
  |------|--------|---------|
248
- | outer_round | 1 | 轮尾评分且 score < 70 且 outer_round < 3 时 → +1;轮首调用不递增 |
366
+ | outer_round | 1 | 轮尾评分且 score < threshold 且 outer_round < 3 时 → +1;轮首调用不递增 |
249
367
  | inner_round | 0 | 内层 loop 每完成一轮 fix → +1;回到外层时重置为 0 |
250
368
  | round_start_score | 0 | 轮首 coverage-analyze 结束后更新(首轮跳过时保持 0);轮尾调用时作为改进比较基准 |
251
369
  | new_cases_count | 0 | 每轮 case-create 结束后更新。若为 0 则跳过 execute+fix,直接进入轮尾评分 |
@@ -262,7 +380,7 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
262
380
  ### 状态检查规则
263
381
 
264
382
  1. 进入 Step 4 时(轮首调用,round 2+ 或 round 1 有已有测试):获取 `uncovered_areas` 和 `score`,将 `score` 保存到 `round_start_score`,**不检查退出条件**
265
- 2. 进入 Step 4 时(轮尾调用,所有 round):检查退出条件(score ≥ 70 / score ≤ round_start_score / outer_round = 3 且 score < 70),不更新 `round_start_score`(轮首已设置)
383
+ 2. 进入 Step 4 时(轮尾调用,所有 round):检查退出条件(score ≥ threshold / score ≤ round_start_score / outer_round = 3 且 score < threshold),不更新 `round_start_score`(轮首已设置)
266
384
  3. 进入 Step 5 后:检查 `new_cases_count == 0` → 跳过 execute+fix,直接回到 Step 4 轮尾评分
267
385
  4. 进入 Step 7 前:检查 `inner_round ≥ 3` → 内层超限,回到外层(轮尾评分)
268
386
  5. 每个报告中的"各轮得分变化"表必须基于状态变量填写,不可凭记忆
@@ -270,24 +388,24 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
270
388
 
271
389
  ## 最终报告格式
272
390
 
273
- 流程结束后,输出最终报告:
391
+ 流程结束后,输出最终报告(`test_type_label` = unit→"单元", integration→"集成"):
274
392
 
275
393
  ```
276
394
  > 生成时间: {YYYY-MM-DD HH:MM:SS}
277
- > 测试类型: integration
395
+ > 测试类型: {test_type}
278
396
  > 测试目录: {test_dir}
279
397
 
280
- ## pyit 集成测试质量报告
398
+ ## pytest {test_type} 测试质量报告
281
399
 
282
400
  ### 环境信息
283
401
  - 项目类型: uv 项目 ✓
284
402
  - 依赖检查: 全部通过 ✓
285
- - 测试类型: integration
286
- - Mock 策略: minimal
403
+ - 测试类型: {test_type}
404
+ - Mock 策略: {config[test_type].mock_strategy}
287
405
 
288
406
  ### 最终结果
289
407
  - 得分: XX / 100(等级: X)
290
- - 覆盖率阈值: 70
408
+ - 覆盖率阈值: {threshold}
291
409
  - 外层迭代: X / 3
292
410
  - 是否达标: [是/否]
293
411
  - 总耗时: Xs
@@ -309,15 +427,42 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
309
427
  |------|------|------|---------|----------|------|
310
428
  | 1 | XX | X | X | X/X | Xs |
311
429
  | 2 | XX | X | X | X/X | Xs |
430
+ ```
431
+
432
+ **覆盖率明细**(权重按配置表):
433
+
434
+ unit:
435
+ ```
436
+ | 维度 | 实际 | 阈值 | 权重 | 得分 |
437
+ |------|------|------|------|------|
438
+ | 行覆盖率 | XX% | 90% | 30 | XX |
439
+ | 分支覆盖率 | XX% | 70% | 30 | XX |
440
+ | 函数覆盖率 | XX% | 90% | 20 | XX |
441
+ ```
312
442
 
313
- ### 覆盖率明细
443
+ integration:
444
+ ```
314
445
  | 维度 | 实际 | 阈值 | 权重 | 得分 |
315
446
  |------|------|------|------|------|
316
447
  | 行覆盖率 | XX% | 70% | 20 | XX |
317
448
  | 分支覆盖率 | XX% | 50% | 20 | XX |
318
449
  | 函数覆盖率 | XX% | 70% | 10 | XX |
450
+ ```
319
451
 
320
- ### 质量明细
452
+ **质量明细**(维度按配置表):
453
+
454
+ unit:
455
+ ```
456
+ | 维度 | 达标/应测 | 权重 | 得分 |
457
+ |------|----------|------|------|
458
+ | 断言完整性 | X/X | 5 | X |
459
+ | 异常路径覆盖 | X/X | 5 | X |
460
+ | 输界值覆盖 | X/X | 5 | X |
461
+ | 命名规范 | X/X | 5 | X |
462
+ ```
463
+
464
+ integration:
465
+ ```
321
466
  | 维度 | 达标/应测 | 权重 | 得分 |
322
467
  |------|----------|------|------|
323
468
  | 场景完整性 | X/X | 15 | X |
@@ -325,7 +470,9 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
325
470
  | 断言完整性 | X/X | 10 | X |
326
471
  | fixture 使用 | X/X | 10 | X |
327
472
  | 命名规范 | X/X | 5 | X |
473
+ ```
328
474
 
475
+ ```
329
476
  ### 未解决项(如有)
330
477
  - [ ] xxx: [原因]
331
478
 
@@ -335,12 +482,11 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
335
482
  | # | 源码文件 | 方法 | Bug 描述 | 状态 | 修复内容/原因 |
336
483
  |---|---------|------|---------|------|-------------|
337
484
  | 1 | MyService.py | create | 返回值逻辑错误 | 已修复 | 修正返回值 |
338
- | 2 | OrderService.py | create_order | 类型校验缺失 | 需人工处理 | 需业务确认预期行为 |
339
485
 
340
486
  ### 退出原因
341
- - [达标] score ≥ 70
487
+ - [达标] score ≥ {threshold}
342
488
  - [无改进] score ≤ round_start_score(本轮无改进)
343
- - [超限] outer_round = 3 且 score < 70
489
+ - [超限] outer_round = 3 且 score < {threshold}
344
490
  ```
345
491
 
346
492
  ### 报告输出
@@ -352,10 +498,23 @@ IT 仅适合有外部依赖的类(Service Class / Integration Point / External
352
498
 
353
499
  ## 规则
354
500
 
355
- 1. 只处理 tests/integration/ 目录下的测试
356
- 2. 最少 Mock,优先真实调用(仅 Mock 不可控的生产 API)
357
- 3. 按业务场景组织用例,不按函数
358
- 4. 验证端到端数据流完整性
359
- 5. 遵循 AGENTS.md:2 空格缩进、类格式、文件名=类名
360
- 6. 测试命名:test_ 前缀(文件名和类名一致)
361
- 7. 不混合单元测试
501
+ **共同规则**:
502
+ 1. 只处理 `tests/{test_type}/` 目录下的测试
503
+ 2. 遵循 AGENTS.md:2 空格缩进、类格式、文件名=类名
504
+ 3. 测试命名:test_ 前缀(文件名和类名一致)
505
+ 4. 不混合测试类型(unit 不混合 integration,反之亦然)
506
+
507
+ **unit 专属规则**:
508
+ - 全部 Mock 外部依赖(HTTP/DB/文件/时间/随机/外部服务)
509
+ - 不修改 conftest.py(除非直接导致失败)
510
+
511
+ **integration 专属规则**:
512
+ - 最少 Mock,优先真实调用(仅 Mock 不可控的生产 API)
513
+ - 按业务场景组织用例,不按函数
514
+ - 验证端到端数据流完整性
515
+
516
+ ## 工具使用约束
517
+
518
+ - 写文件一律用 `write` 工具;读文件用 `read` 工具。
519
+ - 需要中间数据时,用 `write` 工具写入临时文件,再以 stdin 重定向传给 node。
520
+ - 禁止使用未授权的 `cp`/`rm`/`mv` 等命令;需要复制、移动或删除临时文件时,一律用允许的 `node -e` 的 fs 模块完成。
@@ -68,9 +68,9 @@
68
68
  | fixture_file.name | conftest.py | 共享 fixture 文件名 |
69
69
  | fixture_file.data_dir | fixtures | 测试数据目录名 |
70
70
 
71
- ### 目录映射算法(pyut/pyit agent Step 1 唯一权威定义)
71
+ ### 目录映射算法(pytest skill Step 1 唯一权威定义)
72
72
 
73
- > pyut/pyit agent 的 Step 1 直接引用本算法,不另行重复定义。
73
+ > pytest skill 的 Step 1 直接引用本算法,不另行重复定义。
74
74
 
75
75
  当用户未显式指定测试目录时,agent 按以下步骤自动推导 `test_dir`:
76
76
 
@@ -4,7 +4,7 @@ description: |
4
4
  在当前工程 src/ 下创建 pytest-sample 目录,注入一批 demo 类代码。
5
5
  覆盖纯函数、HTTP Mock、DB Mock、文件系统、时间依赖、随机值、环境变量、状态机等多种测试场景。
6
6
  demo 代码中故意注入了 15 个 bug(分 3 个难度梯度),用于触发测试代理的 create→test→fix 循环。
7
- 适用:首次使用 pyut/pyit agent 前的演示验证、测试 agent 流程的端到端测试。
7
+ 适用:首次使用 pytest skill 前的演示验证、测试流程的端到端测试。
8
8
  不适用:生产代码、非测试目的的代码生成。
9
9
  ---
10
10
 
@@ -130,8 +130,8 @@ demo 代码中故意注入了 15 个 bug,分为 3 个难度梯度,用于尽
130
130
  - 总计: 15 个
131
131
 
132
132
  ### 使用方式
133
- 1. 单元测试: /pyut src/pytest-sample
134
- 2. 集成测试: /pyit src/pytest-sample
133
+ 1. 单元测试: /pytest unit src/pytest-sample
134
+ 2. 集成测试: /pytest integration src/pytest-sample
135
135
 
136
136
  ### 场景覆盖说明
137
137
  - 纯函数测试: Calculator.add, Calculator.is_prime
@@ -7,7 +7,7 @@
7
7
  | **编排者** | 宿主内置 agent + 技能 prompt | 自定义 `work` agent(`mode: primary`) |
8
8
  | **编排指令来源** | `using-superpowers` bootstrap + 技能 | agent 定义文件本身 |
9
9
  | **Worker** | 宿主内置 `general-purpose` | 宿主内置 `explore` / `general` |
10
- | **自定义 agent** | 无 | 7 个(work/extract/revise/query/lint/pyit/pyut) |
10
+ | **自定义 agent** | 无 | 3 个(work/query/lint) |
11
11
  | **技能系统** | 14 个技能,通过 `skill` 工具加载 | harness 自己的技能系统 |
12
12
  | **平台** | 跨平台(11+ harness) | 仅 opencode |
13
13
 
@@ -44,7 +44,7 @@ Superpowers 是一个跨平台的 coding agent 增强插件,通过 **skills(
44
44
  |------|------------|-------------------|
45
45
  | 编排者 | 宿主内置 agent + 技能 prompt | 自定义 `work` agent(`mode: primary`) |
46
46
  | Worker | 宿主内置 `general-purpose` | 宿主内置 `explore` / `general` |
47
- | 自定义 agent | 无 | 7 个(work/extract/revise/query/lint/pyit/pyut) |
47
+ | 自定义 agent | 无 | 3 个(work/query/lint) |
48
48
  | 平台 | 跨平台(11+ harness) | 仅 opencode |
49
49
 
50
50
  ## 模块索引