@wwkit/harness 1.0.8 → 1.0.10

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 (110) hide show
  1. package/agents/extract.md +2 -14
  2. package/agents/lint.md +367 -0
  3. package/agents/pyit.md +361 -0
  4. package/agents/pyut.md +347 -0
  5. package/agents/query.md +2 -14
  6. package/agents/revise.md +2 -14
  7. package/agents/work.md +151 -0
  8. package/commands/git-sync.md +218 -0
  9. package/commands/net-port.md +364 -0
  10. package/commands/pyit.md +6 -0
  11. package/commands/pyut.md +6 -0
  12. package/commands/resume.md +104 -0
  13. package/package.json +2 -2
  14. package/skills/better-skill/SKILL.md +124 -0
  15. package/skills/blame-skill/SKILL.md +201 -0
  16. package/skills/lint-ai-fix/SKILL.md +141 -0
  17. package/skills/lint-config-setup/SKILL.md +106 -0
  18. package/skills/lint-config-setup/references/languages/js.md +110 -0
  19. package/skills/lint-config-setup/references/languages/py.md +89 -0
  20. package/skills/lint-env-ensure/SKILL.md +92 -0
  21. package/skills/lint-env-ensure/references/config.md +65 -0
  22. package/skills/lint-language-detect/SKILL.md +79 -0
  23. package/skills/lint-language-detect/references/detect-language.js +65 -0
  24. package/skills/lint-rules-analyze/SKILL.md +129 -0
  25. package/skills/lint-suitability-check/SKILL.md +84 -0
  26. package/skills/lint-tool-fix/SKILL.md +94 -0
  27. package/skills/new-skill/SKILL.md +227 -0
  28. package/skills/new-skill/references/template.md +53 -0
  29. package/skills/new-skill/references/workflow-patterns.md +104 -0
  30. package/skills/pytest-case-create/SKILL.md +327 -0
  31. package/skills/pytest-case-create/references/test-standards.md +244 -0
  32. package/skills/pytest-case-fix/SKILL.md +274 -0
  33. package/skills/pytest-coverage-analyze/SKILL.md +226 -0
  34. package/skills/pytest-coverage-analyze/references/scoring-rules.md +57 -0
  35. package/skills/pytest-env-ensure/SKILL.md +198 -0
  36. package/skills/pytest-env-ensure/references/config.md +145 -0
  37. package/skills/pytest-execute/SKILL.md +155 -0
  38. package/skills/pytest-sample/SKILL.md +164 -0
  39. package/skills/pytest-sample/references/src/pytest-sample/Calculator.py +67 -0
  40. package/skills/pytest-sample/references/src/pytest-sample/ConfigManager.py +68 -0
  41. package/skills/pytest-sample/references/src/pytest-sample/FileProcessor.py +53 -0
  42. package/skills/pytest-sample/references/src/pytest-sample/OrderService.py +82 -0
  43. package/skills/pytest-sample/references/src/pytest-sample/TokenGenerator.py +50 -0
  44. package/skills/pytest-sample/references/src/pytest-sample/UserService.py +45 -0
  45. package/skills/pytest-sample/references/src/pytest-sample/__init__.py +0 -0
  46. package/skills/pytest-suitability-check/SKILL.md +224 -0
  47. package/skills/read-docs/SKILL.md +134 -0
  48. package/skills/read-docs/references/opencode/agents/cases.md +206 -0
  49. package/skills/read-docs/references/opencode/agents/design-pattern.md +47 -0
  50. package/skills/read-docs/references/opencode/agents/detail.md +191 -0
  51. package/skills/read-docs/references/opencode/agents/examples.md +100 -0
  52. package/skills/read-docs/references/opencode/agents/index.md +307 -0
  53. package/skills/read-docs/references/opencode/agents/workflow.md +161 -0
  54. package/skills/read-docs/references/opencode/cli/commands/acp.md +32 -0
  55. package/skills/read-docs/references/opencode/cli/commands/agent.md +16 -0
  56. package/skills/read-docs/references/opencode/cli/commands/attach.md +20 -0
  57. package/skills/read-docs/references/opencode/cli/commands/mcp.md +37 -0
  58. package/skills/read-docs/references/opencode/cli/commands/others.md +49 -0
  59. package/skills/read-docs/references/opencode/cli/commands/plugin.md +13 -0
  60. package/skills/read-docs/references/opencode/cli/commands/provider.md +44 -0
  61. package/skills/read-docs/references/opencode/cli/commands/run.md +81 -0
  62. package/skills/read-docs/references/opencode/cli/commands/serve.md +84 -0
  63. package/skills/read-docs/references/opencode/cli/commands/session.md +38 -0
  64. package/skills/read-docs/references/opencode/cli/commands/web.md +15 -0
  65. package/skills/read-docs/references/opencode/cli/env.md +39 -0
  66. package/skills/read-docs/references/opencode/cli/index.md +19 -0
  67. package/skills/read-docs/references/opencode/cli/tui.md +35 -0
  68. package/skills/read-docs/references/opencode/commands/examples.md +42 -0
  69. package/skills/read-docs/references/opencode/commands/index.md +185 -0
  70. package/skills/read-docs/references/opencode/config/provider.md +152 -0
  71. package/skills/read-docs/references/opencode/formatter/index.md +71 -0
  72. package/skills/read-docs/references/opencode/guide/config.md +419 -0
  73. package/skills/read-docs/references/opencode/guide/formatters.md +70 -0
  74. package/skills/read-docs/references/opencode/guide/index.md +37 -0
  75. package/skills/read-docs/references/opencode/guide/providers.md +31 -0
  76. package/skills/read-docs/references/opencode/guide/rules.md +63 -0
  77. package/skills/read-docs/references/opencode/plugins/examples.md +75 -0
  78. package/skills/read-docs/references/opencode/plugins/index.md +188 -0
  79. package/skills/read-docs/references/opencode/reference/index.md +119 -0
  80. package/skills/read-docs/references/opencode/rule/index.md +78 -0
  81. package/skills/read-docs/references/opencode/skills/detail.md +113 -0
  82. package/skills/read-docs/references/opencode/skills/examples.md +141 -0
  83. package/skills/read-docs/references/opencode/skills/index.md +126 -0
  84. package/skills/read-docs/references/opencode/skills/workflow.md +146 -0
  85. package/skills/read-docs/references/opencode/tests/agent.md +10 -0
  86. package/skills/read-docs/references/opencode/tests/config.md +60 -0
  87. package/skills/read-docs/references/opencode/tests/file.md +12 -0
  88. package/skills/read-docs/references/opencode/tests/serve.md +18 -0
  89. package/skills/read-docs/references/opencode/tests/session.md +31 -0
  90. package/skills/read-docs/references/opencode/tests/web.md +17 -0
  91. package/skills/read-docs/references/opencode/tools/arguments.md +305 -0
  92. package/skills/read-docs/references/opencode/tools/context.md +18 -0
  93. package/skills/read-docs/references/opencode/tools/custom.md +111 -0
  94. package/skills/read-docs/references/opencode/tools/detail.md +104 -0
  95. package/skills/read-docs/references/opencode/tools/examples.md +71 -0
  96. package/skills/read-docs/references/opencode/tools/index.md +56 -0
  97. package/skills/read-docs/references/opencode/tools/lsp.md +26 -0
  98. package/skills/read-docs/references/opencode/tools/mcp.md +132 -0
  99. package/skills/read-docs/references/opencode/train/README.md +135 -0
  100. package/skills/read-docs/references/opencode/train/agent-basic.md +772 -0
  101. package/skills/read-docs/references/opencode/train/command-basic.md +668 -0
  102. package/skills/read-docs/references/opencode/train/config-basic.md +509 -0
  103. package/skills/read-docs/references/opencode/train/index.md +164 -0
  104. package/skills/read-docs/references/opencode/train/practice.md +873 -0
  105. package/skills/read-docs/references/opencode/train/skill-basic.md +608 -0
  106. package/skills/read-docs/references/opencode/tui/commands/config.md +32 -0
  107. package/skills/read-docs/references/opencode/tui/commands/editor.md +47 -0
  108. package/skills/read-docs/references/opencode/tui/commands/index.md +125 -0
  109. package/skills/read-docs/references/opencode/tui/commands/init.md +5 -0
  110. package/skills/read-docs/references/opencode/tui/index.md +26 -0
@@ -0,0 +1,274 @@
1
+ ---
2
+ name: pytest-case-fix
3
+ description: |
4
+ 分析测试失败原因并修复。按失败类型分类处理:断言错误修复测试或源码、Mock 配置错误修正 patch、环境问题标记人工处理。
5
+ 适用:测试代理内层 loop 的修复阶段,修复 pytest-execute 报告的失败用例。
6
+ 不适用:创建新用例(使用 pytest-case-create)、覆盖率分析(使用 pytest-coverage-analyze)。
7
+ ---
8
+
9
+ # 用例修复
10
+
11
+ ## 工作流模式
12
+
13
+ 本 Skill 采用 **顺序执行** 工作流:
14
+
15
+ 1. **分类失败**:按错误类型对失败用例分类
16
+ 2. **分析原因**:逐个分析失败根因
17
+ 3. **执行修复**:按分类进行修复
18
+ 4. **语法验证**:验证修复后的文件语法正确
19
+ 5. **输出记录**:修复记录 + 人工处理项 + 源码 Bug 清单(写入 `{report_dir}/bug_list.md`)
20
+
21
+ ## 输入
22
+
23
+ | 参数 | 必填 | 类型 | 说明 |
24
+ |------|------|------|------|
25
+ | failed_tests | 是 | list | 失败用例清单(来自 pytest-execute) |
26
+ | test_dir | 是 | string | 测试目录路径(由 agent Step 1 统一解析) |
27
+ | report_dir | 是 | string | 报告输出目录(由 agent Step 1 统一解析) |
28
+ | test_type | 是 | string | 测试类型:unit 或 integration |
29
+ | config | 是 | object | 来自 pytest-env-ensure 的配置对象 |
30
+
31
+ ## 输出
32
+
33
+ - 修复记录列表
34
+ - 人工处理项列表
35
+ - 源码 Bug 清单(已修复 + 需人工处理)
36
+ - 是否有修改的结论(有修改 → 回到 execute;无修改 → 内层 loop 退出)
37
+ - 将源码 Bug 清单写入 `{report_dir}/bug_list.md`
38
+
39
+ ---
40
+
41
+ ## 阶段一:分类失败
42
+
43
+ **操作**:按错误类型对失败用例分类
44
+
45
+ | 分类 | 错误类型 | 说明 |
46
+ |------|---------|------|
47
+ | 断言失败 | AssertionError | 测试逻辑有误或源码有 bug |
48
+ | Mock 配置错误 | AttributeError, TypeError | patch 路径不对或 Mock 对象属性缺失 |
49
+ | 导入错误 | ImportError, ModuleNotFoundError | 依赖缺失,环境问题 |
50
+ | 超时 | TimeoutError | 可能有真实网络调用未被 Mock |
51
+ | 其他 | 其他异常 | 未知错误 |
52
+
53
+ ---
54
+
55
+ ## 阶段二:分析原因
56
+
57
+ ### 断言失败(AssertionError)
58
+
59
+ 逐个分析:
60
+
61
+ 1. 读取测试用例代码
62
+ 2. 读取被测源码
63
+ 3. 判断失败原因:
64
+ - **测试逻辑有误**:断言条件写错 → 修复测试
65
+ - **Mock 返回值不对**:Stub 数据与预期不符 → 修复 Mock 的 return_value
66
+ - **源码逻辑有 bug**:测试暴露了真实缺陷 → 修复源码
67
+
68
+ ### Mock 配置错误(AttributeError, TypeError)
69
+
70
+ 1. 检查 `@patch` 路径是否正确
71
+ 2. 检查 Mock 对象是否配置了所需的属性/方法
72
+ 3. 检查 `return_value` / `side_effect` 是否设置
73
+
74
+ ### 导入错误(ImportError, ModuleNotFoundError)
75
+
76
+ 1. 检查是否缺少依赖包
77
+ 2. 标记为 **人工处理**,不在 fix 轮次中解决
78
+
79
+ ### 超时(TimeoutError)
80
+
81
+ 1. 检查是否有真实网络调用未被 Mock
82
+ 2. 修复为 Mock 调用(unit 类型)
83
+ 3. 集成测试的超时可能是环境问题 → 标记人工处理
84
+
85
+ ### 其他
86
+
87
+ 1. 记录详细错误信息
88
+ 2. 标记为 **人工处理**
89
+
90
+ ---
91
+
92
+ ## 阶段三:执行修复
93
+
94
+ ### 修复测试用例
95
+
96
+ | 场景 | 修复操作 |
97
+ |------|---------|
98
+ | 断言条件写错 | 修正断言表达式 |
99
+ | Mock 返回值不对 | 修改 return_value 为正确值 |
100
+ | patch 路径不对 | 修正 @patch 路径为正确的模块路径 |
101
+ | Mock 属性缺失 | 添加 side_effect 或配置 Mock 对象属性 |
102
+ | Stub 数据格式不对 | 修正 Stub 数据结构 |
103
+ | 测试数据有误 | 修正测试输入数据 |
104
+
105
+ ### 修复源码
106
+
107
+ | 场景 | 修复操作 |
108
+ |------|---------|
109
+ | 函数返回值有误 | 修正返回逻辑 |
110
+ | 异常处理不完整 | 补充 try-except 分支 |
111
+ | 边界条件处理错误 | 修正条件判断 |
112
+ | 类型转换错误 | 修正类型处理 |
113
+
114
+ ### 修复原则
115
+
116
+ 1. **只修复失败相关的代码**,不改动其他部分
117
+ 2. **修复测试优先于修复源码**(先确认测试正确,再修源码)
118
+ 3. **一次只修一个失败**,避免引入新问题
119
+ 4. **不修改 conftest.py**(除非失败直接由 conftest 导致)
120
+ 5. **修改源码前必须保存原始内容**(读取并记录文件原始内容,用于回滚)
121
+
122
+ ---
123
+
124
+ ## 阶段四:语法验证与快速测试
125
+
126
+ **操作**:
127
+
128
+ ### 4.1 语法检查
129
+
130
+ 对每个修复的文件运行语法检查:
131
+
132
+ ```
133
+ uv run python -m py_compile "<file>"
134
+ ```
135
+
136
+ ### 4.2 源码修复的快速测试
137
+
138
+ 如果修复了**源码文件**(非测试文件),额外运行对应测试文件的快速验证:
139
+
140
+ ```
141
+ uv run pytest "<对应测试文件>" -v --tb=short --timeout=60 -m {test_type}
142
+ ```
143
+
144
+ **目的**:py_compile 只检查语法,无法发现运行时错误(类型错误、属性不存在等)。快速测试确保源码修复不引入新问题。
145
+
146
+ ### 4.3 回滚机制
147
+
148
+ - 阶段三修复前已保存原始内容
149
+ - 语法检查失败或快速测试引入新错误 → 用原始内容覆盖文件,回滚修改
150
+ - 回滚后标记为人工处理
151
+
152
+ **决策**:
153
+
154
+ | 条件 | 动作 |
155
+ |------|------|
156
+ | 语法正确 + 快速测试通过(或无源码修复) | 进入阶段五 |
157
+ | 语法错误 | 用原始内容回滚,标记为人工处理 |
158
+ | 快速测试引入新错误 | 用原始内容回滚,标记为人工处理 |
159
+ | 快速测试超时 | 回滚源码修改,标记为人工处理 |
160
+
161
+ ---
162
+
163
+ ## 阶段五:输出记录
164
+
165
+ **操作**:
166
+
167
+ 1. 在 chat 中输出修复报告
168
+ 2. 将源码 Bug 清单写入 `{report_dir}/bug_list.md`
169
+
170
+ ### 修复报告(chat 输出)
171
+
172
+ ```
173
+ ## 用例修复报告
174
+
175
+ ### 修复记录
176
+ | # | 文件 | 方法 | 失败类型 | 修复类型 | 修复内容 |
177
+ |---|------|------|---------|---------|---------|
178
+ | 1 | test_MyService.py | test_create_with_valid_data | 断言失败 | 修复测试 | 修正断言条件 |
179
+ | 2 | MyService.py | - | 断言失败 | 修复源码 | 修正返回值逻辑 |
180
+ | 3 | test_MyService.py | test_parse_raises_on_empty | Mock错误 | 修复测试 | 修正 patch 路径 |
181
+
182
+ ### 人工处理项
183
+ | # | 文件 | 方法 | 失败类型 | 原因 |
184
+ |---|------|------|---------|------|
185
+ | 4 | test_MyService.py | test_import_module | 导入错误 | 缺少依赖包 xxx |
186
+
187
+ ### 结论
188
+ - 修复 X 项,人工处理 Y 项
189
+ - [有修改] → 建议重新执行测试
190
+ - [无修改] → 无法自动修复,建议人工介入
191
+ ```
192
+
193
+ ### 源码 Bug 清单(写入 {report_dir}/bug_list.md)
194
+
195
+ 仅记录修复类型为"修复源码"的条目,以及源码层面无法自动修复需人工处理的条目。
196
+
197
+ ```markdown
198
+ # 源码 Bug 清单
199
+
200
+ > 生成时间: {YYYY-MM-DD HH:MM:SS}
201
+ > 测试类型: {test_type}
202
+ > 测试目录: {test_dir}
203
+
204
+ ## 已自动修复
205
+
206
+ | # | 源码文件 | 方法 | Bug 描述 | 修复内容 | 触发用例 |
207
+ |---|---------|------|---------|---------|---------|
208
+ | 1 | MyService.py | create | 返回值逻辑错误 | 修正返回值 | test_create_with_valid_data |
209
+ | 2 | Calculator.py | clamp | min/max 返回值互换 | 修正分支逻辑 | test_clamp_boundary |
210
+
211
+ ## 需人工处理
212
+
213
+ | # | 源码文件 | 方法 | Bug 描述 | 原因 | 触发用例 |
214
+ |---|---------|------|---------|------|---------|
215
+ | 3 | OrderService.py | create_order | 类型校验缺失 | 需业务确认预期行为 | test_create_order_invalid_user_id |
216
+ | 4 | ConfigManager.py | get_bool | truthy 逻辑反转 | 修复后语法错误已回滚,需人工分析 | test_get_bool_unknown |
217
+ ```
218
+
219
+ **源码 Bug 判定规则**:
220
+
221
+ | 条件 | 归类 |
222
+ |------|------|
223
+ | 阶段二判定为"源码逻辑有 bug"且阶段三成功修复 | 已自动修复 |
224
+ | 阶段二判定为"源码逻辑有 bug"但修复后语法验证失败已回滚 | 需人工处理 |
225
+ | 阶段二判定为"源码逻辑有 bug"但无法确定修复方案 | 需人工处理 |
226
+
227
+ **文件写入规则**:
228
+ - 路径:`{report_dir}/bug_list.md`
229
+ - 目录不存在时自动创建
230
+ - 每次内层 loop 执行时覆盖写入(保留最新状态)
231
+ - 无源码 Bug 时仍写入文件,内容为"本次测试未发现源码 Bug"
232
+
233
+ ---
234
+
235
+ ## 决策
236
+
237
+ | 条件 | 动作 |
238
+ |------|------|
239
+ | 有修复(修复数 > 0) | 输出修复记录,回到 pytest-execute 重新执行 |
240
+ | 无修复(全部标记人工处理) | 输出人工处理项,内层 loop 提前退出 |
241
+
242
+ ## 失败处理
243
+
244
+ | 场景 | 处理方式 |
245
+ |------|---------|
246
+ | 修复后语法错误 | 回滚该文件修改,标记人工处理 |
247
+ | 无法确定失败原因 | 记录详情,标记人工处理 |
248
+ | 源码修复引入新问题 | 回滚源码修改,标记人工处理 |
249
+
250
+ ## 一定要做
251
+
252
+ 1. 必须按错误类型分类处理
253
+ 2. 修复测试优先于修复源码
254
+ 3. 一次只修一个失败
255
+ 4. 修改源码前必须保存原始内容(用于回滚)
256
+ 5. 修复后必须验证语法
257
+ 6. 源码修复后必须运行对应测试的快速验证(防止引入新问题)
258
+ 7. 语法错误或快速测试失败必须回滚(用原始内容覆盖)
259
+ 8. 无法修复的必须标记为人工处理
260
+ 9. 必须输出是否有修改的结论
261
+ 10. 修复源码的条目必须记录到源码 Bug 清单
262
+ 11. 源码 Bug 清单必须写入 `{report_dir}/bug_list.md`
263
+ 12. 无源码 Bug 时仍写入 bug_list.md,内容为"本次测试未发现源码 Bug"
264
+
265
+ ## 一定不要做
266
+
267
+ 1. 不要修改与失败无关的代码
268
+ 2. 不要修改 conftest.py(除非直接导致失败)
269
+ 3. 不要在一次修复中改动多个文件(逐个修复)
270
+ 4. 不要跳过语法验证
271
+ 5. 不要跳过源码修复后的快速测试
272
+ 6. 不要忽略语法验证或快速测试失败(必须回滚)
273
+ 7. 不要尝试修复导入错误(标记人工处理)
274
+ 8. 不要在未保存原始内容的情况下修改源码(无法回滚)
@@ -0,0 +1,226 @@
1
+ ---
2
+ name: pytest-coverage-analyze
3
+ description: |
4
+ 运行 pytest 覆盖率分析并按评分规则计算质量得分。解析 coverage.json 提取覆盖率数据,扫描测试文件检查质量维度。
5
+ 适用:测试代理外层 loop 的分析阶段,评估当前测试覆盖范围和质量。
6
+ 不适用:非 pytest 项目、非覆盖率相关的代码分析。
7
+ ---
8
+
9
+ # 覆盖率与质量分析
10
+
11
+ ## 工作流模式
12
+
13
+ 本 Skill 采用 **顺序执行** 工作流:
14
+
15
+ 1. **运行覆盖率**:执行 pytest --cov 生成 JSON 报告
16
+ 2. **解析覆盖率**:从 coverage.json 提取行/分支/函数覆盖率
17
+ 3. **质量检查**:扫描测试文件检查质量维度
18
+ 4. **评分计算**:按评分规则计算总分
19
+ 5. **输出结果**:得分 + 未覆盖区域 + 改进建议
20
+
21
+ ## 输入
22
+
23
+ | 参数 | 必填 | 类型 | 说明 |
24
+ |------|------|------|------|
25
+ | target | 是 | string | 被测模块路径(如 src/mypackage) |
26
+ | test_dir | 是 | string | 测试目录路径(由 agent Step 1 统一解析) |
27
+ | report_dir | 是 | string | 报告输出目录(用于 coverage.json 输出路径) |
28
+ | test_type | 是 | string | 测试类型:unit 或 integration |
29
+ | config | 是 | object | 来自 pytest-env-ensure 的配置对象 |
30
+ | previous_score | 否 | number | 上一轮得分(用于无改进检测) |
31
+
32
+ ## 输出
33
+
34
+ - 总分(0-100)
35
+ - 各维度得分明细
36
+ - 未覆盖文件/函数/分支列表
37
+ - 改进建议
38
+ - 是否达标的结论
39
+
40
+ ---
41
+
42
+ ## 阶段一:运行覆盖率
43
+
44
+ **操作**:
45
+
46
+ 使用传入的 `test_dir` 运行覆盖率分析:
47
+
48
+ ```
49
+ # unit 超时 60s,integration 超时 300s
50
+ uv run pytest "{test_dir}" --cov="{target}" --cov-report=term --cov-report=json:"{report_dir}/coverage.json" --cov-report=html:"{report_dir}/htmlcov" --timeout={timeout} -m {test_type}
51
+ ```
52
+
53
+ **超时配置**:
54
+ - test_type=unit → timeout=60
55
+ - test_type=integration → timeout=300
56
+ - 超时值来自 config.md 的 `test_timeout` 配置
57
+
58
+ **失败处理**:
59
+
60
+ | 条件 | 动作 |
61
+ |------|------|
62
+ | pytest 执行成功 | 进入阶段二 |
63
+ | pytest 有失败用例 | 仍然解析覆盖率(覆盖率基于已执行的用例),记录失败数 |
64
+ | pytest 执行错误(非测试失败) | 退出,输出错误信息 |
65
+
66
+ ---
67
+
68
+ ## 阶段二:解析覆盖率
69
+
70
+ **输入**:`{report_dir}/coverage.json` 文件
71
+
72
+ **操作**:
73
+
74
+ 1. 读取 `coverage.json`
75
+ 2. 提取 `totals` 字段:
76
+ - `num_statements`, `covered_lines` → 行覆盖率
77
+ - `num_branches`, `covered_branches` → 分支覆盖率
78
+ - `num_functions`, `covered_functions` → 函数覆盖率
79
+ 3. 提取 `files` 字段:每个文件的覆盖率明细
80
+ 4. 识别未覆盖的文件、函数、分支
81
+
82
+ **计算公式**:
83
+
84
+ - 行覆盖率 = num_statements > 0 ? covered_lines / num_statements × 100% : 100%
85
+ - 分支覆盖率 = num_branches > 0 ? covered_branches / num_branches × 100% : 100%
86
+ - 函数覆盖率 = num_functions > 0 ? covered_functions / num_functions × 100% : 100%
87
+
88
+ > **除零保护**:当分母为 0 时(源码无分支/无函数/无语句),该项覆盖率记为 100%(满分)。
89
+ > 这与 `references/scoring-rules.md` 的"分母为 0 时该项给满分"规则一致。
90
+
91
+ ---
92
+
93
+ ## 阶段三:质量检查
94
+
95
+ **操作**:扫描传入的 `test_dir` 目录下所有测试文件
96
+
97
+ ### 检查项(按 test_type 加载对应权重)
98
+
99
+ **unit 质量维度(20 分)**:
100
+
101
+ | 维度 | 检查方法 |
102
+ |------|---------|
103
+ | 断言完整性(5) | 统计每个 test 函数是否含 `assert` 关键字 |
104
+ | 异常路径覆盖(5) | 源码中含 `raise`/`try` 的函数,测试中是否有 `pytest.raises` |
105
+ | 边界值覆盖(5) | 源码中含 `if`/`elif` 的函数,测试用例数 ≥ 分支数 |
106
+ | 命名规范(5) | test 函数名匹配 `^test_\w+_\w+$` |
107
+
108
+ **integration 质量维度(50 分)**:
109
+
110
+ | 维度 | 检查方法 |
111
+ |------|---------|
112
+ | 场景完整性(15) | 核心业务场景是否都有对应测试(按源码公开方法数统计) |
113
+ | 数据流验证(10) | 测试中是否验证了输入→处理→输出完整链路(含多步 assert) |
114
+ | 断言完整性(10) | 每个 test 函数至少含 1 个 assert |
115
+ | fixture 使用(10) | 是否合理使用 setup/teardown fixture |
116
+ | 命名规范(5) | test 函数名匹配 `^test_\w+_\w+$` |
117
+
118
+ **通用规则**:
119
+ - 分母为 0 时(无适用项),该项给满分
120
+ - 超限封顶:`min(实际/阈值, 1.0)`
121
+
122
+ ---
123
+
124
+ ## 阶段四:评分计算
125
+
126
+ **输入**:覆盖率数据 + 质量检查结果
127
+
128
+ **操作**:按 `references/scoring-rules.md` 的评分规则计算总分
129
+
130
+ **评分公式**:
131
+
132
+ ```
133
+ 总分 = 行覆盖率得分 + 分支覆盖率得分 + 函数覆盖率得分 + 质量维度得分
134
+
135
+ 单项得分 = min(实际值/阈值, 1.0) × 满分
136
+ ```
137
+
138
+ **等级**:
139
+
140
+ | 等级 | 分数 |
141
+ |------|------|
142
+ | A | 90-100 |
143
+ | B | 80-89 |
144
+ | C | 60-79 |
145
+ | D | <60 |
146
+
147
+ ---
148
+
149
+ ## 阶段五:输出结果
150
+
151
+ **输出格式**:
152
+
153
+ ```
154
+ ## 覆盖率与质量分析报告
155
+
156
+ ### 总分:XX / 100(等级:X)
157
+
158
+ ### 覆盖率明细
159
+ | 维度 | 实际 | 阈值 | 权重 | 得分 |
160
+ |------|------|------|------|------|
161
+ | 行覆盖率 | XX% | XX% | XX | XX |
162
+ | 分支覆盖率 | XX% | XX% | XX | XX |
163
+ | 函数覆盖率 | XX% | XX% | XX | XX |
164
+
165
+ ### 质量明细
166
+ | 维度 | 达标/应测 | 权重 | 得分 |
167
+ |------|----------|------|------|
168
+ | 断言完整性 | X/X | X | X |
169
+ | 异常路径覆盖 | X/X | X | X |
170
+ | 边界值覆盖 | X/X | X | X |
171
+ | 命名规范 | X/X | X | X |
172
+
173
+ ### 未覆盖区域
174
+ | 文件 | 未覆盖函数 | 未覆盖行数 |
175
+ |------|-----------|-----------|
176
+ | src/xxx.py | func_a, func_b | 15 |
177
+
178
+ ### 改进建议
179
+ 1. 为 func_a 添加正向测试用例
180
+ 2. 为 func_b 的 if 分支添加边界值用例
181
+ 3. ...
182
+
183
+ ### 结论
184
+ - 得分 XX,阈值 XX → [达标/未达标]
185
+ - [未达标] → 建议进入用例创建阶段
186
+ ```
187
+
188
+ ---
189
+
190
+ ## 决策
191
+
192
+ | 条件 | 动作 |
193
+ |------|------|
194
+ | score ≥ coverage_threshold | 输出"达标",流程结束 |
195
+ | score < coverage_threshold | 输出未覆盖区域,交给 pytest-case-create |
196
+ | score ≤ previous_score(非首轮) | 输出"无改进",提前退出外层 loop |
197
+
198
+ ## 失败处理
199
+
200
+ | 场景 | 处理方式 |
201
+ |------|---------|
202
+ | coverage.json 不存在 | 退出,提示覆盖率报告未生成 |
203
+ | 目标模块路径无效 | 退出,提示路径不存在 |
204
+ | 测试目录不存在 | 输出 0 分,提示需要创建测试目录 |
205
+ | 测试目录为空(无 test_*.py 文件) | 输出 0 分,将全部源码文件列为未覆盖,提示需要先创建用例 |
206
+ | pytest 超时 | 退出,提示测试执行超时,建议检查是否有 hang 住的用例或增加 timeout 配置 |
207
+
208
+ > **注意**:agent 在首轮检测到 test_dir 为空时会跳过本技能,直接进入 case-create。
209
+ > 此场景仅作为兜底保护,确保即使 agent 未跳过也不会崩溃。
210
+
211
+ ## 一定要做
212
+
213
+ 1. 必须使用传入的 test_dir 运行覆盖率分析,并根据 test_type 选择评分权重
214
+ 2. 覆盖率数据必须来自 coverage.json,不做主观判断
215
+ 3. 质量检查必须通过文件扫描,不猜测
216
+ 4. 分母为 0 时该项给满分(覆盖率维度和质量维度均适用)
217
+ 5. 必须输出未覆盖区域清单(供 case-create 使用)
218
+ 6. 非首轮时必须检查是否无改进
219
+
220
+ ## 一定不要做
221
+
222
+ 1. 不要混合 unit 和 integration 的覆盖率数据
223
+ 2. 不要修改源码或测试文件
224
+ 3. 不要跳过质量检查只看覆盖率
225
+ 4. 不要主观判断测试质量,只做可程序化检查的判断
226
+ 5. 不要忽略 coverage.json 解析错误
@@ -0,0 +1,57 @@
1
+ # 评分规则
2
+
3
+ > 覆盖率数据完全来自 `coverage.json`(pytest-cov 生成),质量维度通过文件扫描检查,无主观判断。
4
+
5
+ ## 单元测试评分(unit)— 满分 100
6
+
7
+ ### 覆盖率维度(80 分)
8
+
9
+ | 维度 | 满分 | 阈值 | 数据来源 | 计分公式 |
10
+ |------|------|------|---------|---------|
11
+ | 行覆盖率 | 30 | 90% | coverage.json: covered_lines / num_statements | `min(实际/阈值, 1) × 30` |
12
+ | 分支覆盖率 | 30 | 70% | coverage.json: covered_branches / num_branches | `min(实际/阈值, 1) × 30` |
13
+ | 函数覆盖率 | 20 | 90% | coverage.json: covered_functions / num_functions | `min(实际/阈值, 1) × 20` |
14
+
15
+ ### 质量维度(20 分)
16
+
17
+ | 维度 | 满分 | 检查方法 | 计分公式 |
18
+ |------|------|---------|---------|
19
+ | 断言完整性 | 5 | 扫描测试文件,统计含 `assert` 关键字的 test 函数比例 | `(有assert函数数 / 总函数数) × 5` |
20
+ | 异常路径覆盖 | 5 | 源码含 `raise`/`try` 的函数,测试中是否有对应 `pytest.raises` | `(有异常测试数 / 应测异常函数数) × 5` |
21
+ | 边界值覆盖 | 5 | 源码含 `if`/`elif` 的函数,测试用例数 ≥ 分支数 | `(达标函数数 / 应测函数数) × 5` |
22
+ | 命名规范 | 5 | test 函数名匹配 `^test_\w+_\w+$` | `(规范命名数 / 总数) × 5` |
23
+
24
+ ## 集成测试评分(integration)— 满分 100
25
+
26
+ ### 覆盖率维度(50 分)
27
+
28
+ | 维度 | 满分 | 阈值 | 数据来源 | 计分公式 |
29
+ |------|------|------|---------|---------|
30
+ | 行覆盖率 | 20 | 70% | coverage.json: covered_lines / num_statements | `min(实际/阈值, 1) × 20` |
31
+ | 分支覆盖率 | 20 | 50% | coverage.json: covered_branches / num_branches | `min(实际/阈值, 1) × 20` |
32
+ | 函数覆盖率 | 10 | 70% | coverage.json: covered_functions / num_functions | `min(实际/阈值, 1) × 10` |
33
+
34
+ ### 质量维度(50 分)
35
+
36
+ | 维度 | 满分 | 检查方法 | 计分公式 |
37
+ |------|------|---------|---------|
38
+ | 场景完整性 | 15 | 核心业务场景是否都有对应测试(按源码公开方法数统计) | `(有测试的场景数 / 应测场景数) × 15` |
39
+ | 数据流验证 | 10 | 测试中是否验证了输入→处理→输出完整链路(含多步 assert) | `(有数据流验证的函数数 / 总函数数) × 10` |
40
+ | 断言完整性 | 10 | 每个测试函数至少含 1 个 assert | `(有assert函数数 / 总函数数) × 10` |
41
+ | fixture 使用 | 10 | 是否合理使用 setup/teardown fixture | `(有fixture的测试类数 / 总类数) × 10` |
42
+ | 命名规范 | 5 | test 函数名匹配 `^test_\w+_\w+$` | `(规范命名数 / 总数) × 5` |
43
+
44
+ ## 通用规则
45
+
46
+ - **分母为 0**:若应测数为 0(无适用项),该项直接给满分。
47
+ - **超限封顶**:`min(实际/阈值, 1.0)` 确保单项不超过满分。
48
+ - **数据来源**:覆盖率维度完全依赖 coverage.json;质量维度通过 grep/扫描测试文件检查。
49
+
50
+ ## 等级
51
+
52
+ | 等级 | 分数范围 | 含义 |
53
+ |------|---------|------|
54
+ | A | 90-100 | 优秀 |
55
+ | B | 80-89 | 合格 |
56
+ | C | 60-79 | 需改进 |
57
+ | D | <60 | 不合格 |