@wwkit/harness 1.0.27 → 1.0.29
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.
- package/bin/index.js +10 -0
- package/package.json +3 -2
- package/skills/extract/SKILL.md +43 -68
- package/skills/extract/references/detail.md +1 -1
- package/skills/extract/references/list.md +3 -3
- package/skills/extract/references/navi.md +1 -1
- package/skills/jstest/SKILL.md +561 -0
- package/skills/jstest/references/case-create.md +327 -0
- package/skills/jstest/references/case-fix.md +273 -0
- package/skills/jstest/references/config.md +148 -0
- package/skills/jstest/references/coverage-analyze.md +247 -0
- package/skills/jstest/references/env-ensure.md +210 -0
- package/skills/jstest/references/execute.md +168 -0
- package/skills/jstest/references/sample.md +166 -0
- package/skills/jstest/references/scoring-rules.md +75 -0
- package/skills/jstest/references/src/jstest-sample/Calculator.js +80 -0
- package/skills/jstest/references/src/jstest-sample/ConfigManager.js +72 -0
- package/skills/jstest/references/src/jstest-sample/FileProcessor.js +57 -0
- package/skills/jstest/references/src/jstest-sample/OrderService.js +98 -0
- package/skills/jstest/references/src/jstest-sample/TokenGenerator.js +60 -0
- package/skills/jstest/references/src/jstest-sample/UserService.js +56 -0
- package/skills/jstest/references/src/jstest-sample/index.js +6 -0
- package/skills/jstest/references/suitability-check.md +232 -0
- package/skills/jstest/references/test-standards.md +288 -0
- package/skills/pytest/SKILL.md +38 -30
- package/skills/query/SKILL.md +16 -47
- package/skills/revise/SKILL.md +52 -96
- package/skills/revise/references/article.md +12 -15
- package/skills/revise/references/gallery.md +11 -15
- package/skills/revise/references/question.md +11 -15
- package/skills/revise/references/status.md +10 -14
- package/src/config.js +29 -0
- package/src/config.json5 +19 -0
- package/skills/extract/references/format-aliases.json5 +0 -22
- package/skills/extract/references/input.schema.json5 +0 -23
- package/skills/query/references/input.schema.json5 +0 -25
- package/skills/revise/references/format-aliases.json5 +0 -22
- package/skills/revise/references/input.schema.json5 +0 -28
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# jstest 测试代理配置清单
|
|
2
|
+
|
|
3
|
+
> 本文件是测试代理的全局配置,agent 启动时首先读取,后续所有 skill 共享。
|
|
4
|
+
|
|
5
|
+
## 依赖工具
|
|
6
|
+
|
|
7
|
+
| name | check | required | install |
|
|
8
|
+
|------|-------|----------|---------|
|
|
9
|
+
| node | `node --version` | true | null(系统级工具,需手动安装) |
|
|
10
|
+
| jest | `npx jest --version` | true | `pnpm add -D jest` 或 `npm install --save-dev jest` |
|
|
11
|
+
| supertest | `node -e "require.resolve('supertest')"` | false | `pnpm add -D supertest` 或 `npm install --save-dev supertest` |
|
|
12
|
+
|
|
13
|
+
## 环境检查
|
|
14
|
+
|
|
15
|
+
| 参数 | 值 | 说明 |
|
|
16
|
+
|------|-----|------|
|
|
17
|
+
| npm_project_check | true | 必须是 npm/pnpm 项目(package.json + node_modules/) |
|
|
18
|
+
| install_retry | 3 | 插件安装失败重试次数 |
|
|
19
|
+
|
|
20
|
+
## 超时配置
|
|
21
|
+
|
|
22
|
+
| 参数 | 值 | 说明 |
|
|
23
|
+
|------|-----|------|
|
|
24
|
+
| test_timeout_unit | 60 | 单元测试单用例超时(秒) |
|
|
25
|
+
| test_timeout_integration | 300 | 集成测试单用例超时(秒) |
|
|
26
|
+
|
|
27
|
+
## Loop 控制
|
|
28
|
+
|
|
29
|
+
| 参数 | 值 | 说明 |
|
|
30
|
+
|------|-----|------|
|
|
31
|
+
| outer_max | 3 | 外层 loop(coverage→create→execute)最大轮次 |
|
|
32
|
+
| inner_max | 3 | 内层 loop(fix→execute)最大轮次 |
|
|
33
|
+
|
|
34
|
+
## 测试指标 — 单元测试(unit)
|
|
35
|
+
|
|
36
|
+
| 参数 | 值 | 说明 |
|
|
37
|
+
|------|-----|------|
|
|
38
|
+
| coverage_threshold | 90 | 覆盖率达标线 |
|
|
39
|
+
| line_coverage_weight | 30 | 行覆盖率权重 |
|
|
40
|
+
| branch_coverage_weight | 30 | 分支覆盖率权重 |
|
|
41
|
+
| function_coverage_weight | 20 | 函数覆盖率权重 |
|
|
42
|
+
| test_quality_weight | 20 | 用例质量权重 |
|
|
43
|
+
|
|
44
|
+
## 测试指标 — 集成测试(integration)
|
|
45
|
+
|
|
46
|
+
| 参数 | 值 | 说明 |
|
|
47
|
+
|------|-----|------|
|
|
48
|
+
| coverage_threshold | 70 | 覆盖率达标线 |
|
|
49
|
+
| line_coverage_weight | 20 | 行覆盖率权重 |
|
|
50
|
+
| branch_coverage_weight | 20 | 分支覆盖率权重 |
|
|
51
|
+
| function_coverage_weight | 10 | 函数覆盖率权重 |
|
|
52
|
+
| test_quality_weight | 50 | 用例质量权重(更重场景质量) |
|
|
53
|
+
|
|
54
|
+
## 命名规则
|
|
55
|
+
|
|
56
|
+
| 参数 | 值 | 说明 |
|
|
57
|
+
|------|-----|------|
|
|
58
|
+
| test_root | tests | 测试根目录 |
|
|
59
|
+
| dir_mapping_pattern | `tests/{type}/{package_module}` | 归一化仅去除 src/ 前缀,保留包名 |
|
|
60
|
+
| report_dir_pattern | `{test_dir}/reports/{YYYYMMDD_HHMMSS}/` | 报告输出目录 |
|
|
61
|
+
| report.test_report | `test_report.md` | 最终测试报告文件名 |
|
|
62
|
+
| report.bug_list | `bug_list.md` | 源码 Bug 清单文件名 |
|
|
63
|
+
| file.pattern | `{ModuleName}.test.js` | 测试文件命名 |
|
|
64
|
+
| describe.pattern | `describe('ModuleName')` | describe 块命名(与被测模块名一致) |
|
|
65
|
+
| test.pattern | `test('should {action} {expected}')` | 测试用例命名 |
|
|
66
|
+
| setup_file.name | `jest.setup.js` | 共享 setup 文件名 |
|
|
67
|
+
| setup_file.data_dir | `fixtures` | 测试数据目录名 |
|
|
68
|
+
|
|
69
|
+
### 目录映射算法(jstest skill Step 1 唯一权威定义)
|
|
70
|
+
|
|
71
|
+
> jstest skill 的 Step 1 直接引用本算法,不另行重复定义。
|
|
72
|
+
|
|
73
|
+
当用户未显式指定测试目录时,agent 按以下步骤自动推导 `test_dir`:
|
|
74
|
+
|
|
75
|
+
**输入**: `source_path`(源码路径),`test_type`(unit 或 integration)
|
|
76
|
+
|
|
77
|
+
**Step 1: 归一化源码路径**
|
|
78
|
+
|
|
79
|
+
按顺序执行:
|
|
80
|
+
|
|
81
|
+
1. 文件 → 取父目录
|
|
82
|
+
2. 绝对路径 → 转为相对路径(相对于项目根目录)
|
|
83
|
+
3. 含 `..` → 先 resolve 为标准路径再继续
|
|
84
|
+
4. 为 `.` 或空 → 报错"请提供子目录路径,如 src/mymodule"
|
|
85
|
+
5. 去除开头的 `./`
|
|
86
|
+
6. 去除开头的 `src/`(仅去除一次)
|
|
87
|
+
7. 归一化后为空 → 报错"归一化后路径为空,请提供 src/ 下的子目录"
|
|
88
|
+
|
|
89
|
+
**归一化规则**:仅去除 `src/` 前缀,**保留包名及子模块路径**。无 `src/` 前缀的路径(flat layout)保持原样。
|
|
90
|
+
|
|
91
|
+
**Step 2: 映射**
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
test_dir = tests/{test_type}/{归一化路径}/
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Step 3: 验证与创建**
|
|
98
|
+
|
|
99
|
+
- `tests/` 不存在 → 自动创建 `tests/{test_type}/` 目录结构
|
|
100
|
+
- 映射目录不存在 → 自动创建,标记为全新模式(无已有测试)
|
|
101
|
+
|
|
102
|
+
### 映射示例
|
|
103
|
+
|
|
104
|
+
| 源码路径 | test_type | 归一化 | 自动推导 test_dir |
|
|
105
|
+
|---------|-----------|--------|------------------|
|
|
106
|
+
| `src/mymodule` | unit | `mymodule` | `tests/unit/mymodule/` |
|
|
107
|
+
| `src/mypackage/sub` | unit | `mypackage/sub` | `tests/unit/mypackage/sub/` |
|
|
108
|
+
| `src/mypackage/MyService.js` | unit | `mypackage` | `tests/unit/mypackage/` |
|
|
109
|
+
| `src/mymodule` | integration | `mymodule` | `tests/integration/mymodule/` |
|
|
110
|
+
| `lib/util` | integration | `lib/util` | `tests/integration/lib/util/` |
|
|
111
|
+
| `mypackage/sub`(flat layout) | unit | `mypackage/sub` | `tests/unit/mypackage/sub/` |
|
|
112
|
+
|
|
113
|
+
### 命名示例
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
源码路径: src/mypackage/MyService.js
|
|
117
|
+
模块名: MyService
|
|
118
|
+
测试目录: tests/unit/mypackage/
|
|
119
|
+
测试文件: tests/unit/mypackage/MyService.test.js
|
|
120
|
+
describe: describe('MyService', () => { ... })
|
|
121
|
+
test: test('should return expected result when ...', () => { ... })
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 测试类型
|
|
125
|
+
|
|
126
|
+
### unit(单元测试)
|
|
127
|
+
|
|
128
|
+
| 参数 | 值 | 说明 |
|
|
129
|
+
|------|-----|------|
|
|
130
|
+
| dir | tests/unit | 测试目录 |
|
|
131
|
+
| jest_test_category | unit | jest test category(describe 命名约定) |
|
|
132
|
+
| mock_strategy | full | 全部 Mock 外部依赖 |
|
|
133
|
+
| coverage_focus | line, branch, function | 覆盖率关注点 |
|
|
134
|
+
| timeout | 60 | 单用例超时(秒) |
|
|
135
|
+
| run_command | `node --experimental-vm-modules node_modules/jest/bin/jest.js --no-cache --coverage` | ESM 项目运行命令 |
|
|
136
|
+
| run_command_cjs | `npx jest --no-cache --coverage` | CommonJS 项目运行命令 |
|
|
137
|
+
|
|
138
|
+
### integration(集成测试)
|
|
139
|
+
|
|
140
|
+
| 参数 | 值 | 说明 |
|
|
141
|
+
|------|-----|------|
|
|
142
|
+
| dir | tests/integration | 测试目录 |
|
|
143
|
+
| jest_test_category | integration | jest test category(describe 命名约定) |
|
|
144
|
+
| mock_strategy | minimal | 最少 Mock,真实调用 |
|
|
145
|
+
| coverage_focus | scenario, flow | 覆盖率关注点 |
|
|
146
|
+
| timeout | 300 | 单用例超时(秒) |
|
|
147
|
+
| run_command | `node --experimental-vm-modules node_modules/jest/bin/jest.js --no-cache --coverage` | ESM 项目运行命令 |
|
|
148
|
+
| run_command_cjs | `npx jest --no-cache --coverage` | CommonJS 项目运行命令 |
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
> **原 skill**: `jstest-coverage-analyze`(已合并入 jstest)
|
|
2
|
+
> **适用**: 测试代理外层 loop 的分析阶段,评估当前测试覆盖范围和质量。
|
|
3
|
+
> **不适用**: 非 jest 项目、非覆盖率相关的代码分析。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 覆盖率与质量分析
|
|
8
|
+
|
|
9
|
+
## 工作流模式
|
|
10
|
+
|
|
11
|
+
本 Skill 采用 **顺序执行** 工作流:
|
|
12
|
+
|
|
13
|
+
1. **运行覆盖率**:执行 jest --coverage 生成 JSON 报告
|
|
14
|
+
2. **解析覆盖率**:从 coverage-summary.json 提取行/分支/函数覆盖率
|
|
15
|
+
3. **质量检查**:扫描测试文件检查质量维度
|
|
16
|
+
4. **评分计算**:按评分规则计算总分
|
|
17
|
+
5. **输出结果**:得分 + 未覆盖区域 + 改进建议
|
|
18
|
+
|
|
19
|
+
## 输入
|
|
20
|
+
|
|
21
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
22
|
+
|------|------|------|------|
|
|
23
|
+
| target | 是 | string | 被测模块路径(如 src/mypackage) |
|
|
24
|
+
| test_dir | 是 | string | 测试目录路径(由 agent Step 1 统一解析) |
|
|
25
|
+
| report_dir | 是 | string | 报告输出目录(用于 coverage 输出路径) |
|
|
26
|
+
| test_type | 是 | string | 测试类型:unit 或 integration |
|
|
27
|
+
| config | 是 | object | 来自 jstest-env-ensure 的配置对象 |
|
|
28
|
+
| previous_score | 否 | number | 上一轮得分(用于无改进检测) |
|
|
29
|
+
|
|
30
|
+
## 输出
|
|
31
|
+
|
|
32
|
+
- 总分(0-100)
|
|
33
|
+
- 各维度得分明细
|
|
34
|
+
- 未覆盖文件/函数/分支列表
|
|
35
|
+
- 改进建议
|
|
36
|
+
- 是否达标的结论
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 阶段一:运行覆盖率
|
|
41
|
+
|
|
42
|
+
**操作**:
|
|
43
|
+
|
|
44
|
+
使用传入的 `test_dir` 运行覆盖率分析:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
# unit 超时 60000ms,integration 超时 300000ms
|
|
48
|
+
node --experimental-vm-modules node_modules/jest/bin/jest.js --no-cache --coverage --coverageReporters=json-summary --coverageReporters=text --testTimeout={timeout} {test_dir}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**超时配置**:
|
|
52
|
+
- test_type=unit → timeout=60000
|
|
53
|
+
- test_type=integration → timeout=300000
|
|
54
|
+
- 超时值来自 config.md 的 `test_timeout` 配置
|
|
55
|
+
|
|
56
|
+
**覆盖率报告输出路径**:
|
|
57
|
+
- jest 默认将覆盖率报告输出到 `coverage/` 目录
|
|
58
|
+
- 完整路径:`{report_dir}/coverage/coverage-summary.json`
|
|
59
|
+
|
|
60
|
+
**失败处理**:
|
|
61
|
+
|
|
62
|
+
| 条件 | 动作 |
|
|
63
|
+
|------|------|
|
|
64
|
+
| jest 执行成功 | 进入阶段二 |
|
|
65
|
+
| jest 有失败用例 | 仍然解析覆盖率(覆盖率基于已执行的用例),记录失败数 |
|
|
66
|
+
| jest 执行错误(非测试失败) | 退出,输出错误信息 |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 阶段二:解析覆盖率
|
|
71
|
+
|
|
72
|
+
**输入**:`{report_dir}/coverage/coverage-summary.json` 文件
|
|
73
|
+
|
|
74
|
+
**操作**:
|
|
75
|
+
|
|
76
|
+
1. 读取 `coverage-summary.json`
|
|
77
|
+
2. 提取 `total` 字段:
|
|
78
|
+
- `total.lines.total`, `total.lines.covered`, `total.lines.pct` → 行覆盖率
|
|
79
|
+
- `total.branches.total`, `total.branches.covered`, `total.branches.pct` → 分支覆盖率
|
|
80
|
+
- `total.functions.total`, `total.functions.covered`, `total.functions.pct` → 函数覆盖率
|
|
81
|
+
3. 提取各文件条目:每个文件的覆盖率明细(key 为文件绝对路径)
|
|
82
|
+
4. 识别未覆盖的文件、函数、分支
|
|
83
|
+
|
|
84
|
+
**jest coverage-summary.json 格式**:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"total": {
|
|
89
|
+
"lines": { "total": 100, "covered": 85, "skipped": 0, "pct": 85 },
|
|
90
|
+
"statements": { "total": 120, "covered": 100, "skipped": 0, "pct": 83.33 },
|
|
91
|
+
"functions": { "total": 20, "covered": 15, "skipped": 0, "pct": 75 },
|
|
92
|
+
"branches": { "total": 30, "covered": 20, "skipped": 0, "pct": 66.67 }
|
|
93
|
+
},
|
|
94
|
+
"/absolute/path/to/file.js": {
|
|
95
|
+
"lines": { "total": 50, "covered": 40, "skipped": 0, "pct": 80 },
|
|
96
|
+
"statements": { ... },
|
|
97
|
+
"functions": { ... },
|
|
98
|
+
"branches": { ... }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**计算公式**:
|
|
104
|
+
|
|
105
|
+
- 行覆盖率 = total.lines.pct(jest 已计算百分比)
|
|
106
|
+
- 分支覆盖率 = total.branches.pct
|
|
107
|
+
- 函数覆盖率 = total.functions.pct
|
|
108
|
+
|
|
109
|
+
> **除零保护**:当 jest 报告中 pct 为 0 且 total 为 0 时(源码无分支/无函数/无语句),该项覆盖率记为 100%(满分)。
|
|
110
|
+
> 这与 `scoring-rules.md` 的"分母为 0 时该项给满分"规则一致。
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 阶段三:质量检查
|
|
115
|
+
|
|
116
|
+
**操作**:扫描传入的 `test_dir` 目录下所有测试文件(`*.test.js` / `*.test.ts`)
|
|
117
|
+
|
|
118
|
+
### 检查项(按 test_type 加载对应权重)
|
|
119
|
+
|
|
120
|
+
**unit 质量维度(20 分)**:
|
|
121
|
+
|
|
122
|
+
| 维度 | 检查方法 |
|
|
123
|
+
|------|---------|
|
|
124
|
+
| 断言完整性(5) | 统计每个 test/it 回调函数内是否含 `expect(` 调用 |
|
|
125
|
+
| 异常路径覆盖(5) | 源码中含 `throw`/`try` 的函数,测试中是否有 `toThrow` 或 `try-catch` |
|
|
126
|
+
| 边界值覆盖(5) | 源码中含 `if`/`else` 的函数,测试用例数 ≥ 分支数(检查 `test.each`/`it.each`) |
|
|
127
|
+
| 命名规范(5) | describe 名匹配 `^ModuleName$`,test/it 名匹配 `^should .+$` |
|
|
128
|
+
|
|
129
|
+
**integration 质量维度(50 分)**:
|
|
130
|
+
|
|
131
|
+
| 维度 | 检查方法 |
|
|
132
|
+
|------|---------|
|
|
133
|
+
| 场景完整性(15) | 核心业务场景是否都有对应测试(按源码公开导出方法数统计) |
|
|
134
|
+
| 数据流验证(10) | 测试中是否验证了输入→处理→输出完整链路(含多步 expect) |
|
|
135
|
+
| 断言完整性(10) | 每个 test/it 回调函数至少含 1 个 expect 调用 |
|
|
136
|
+
| setup/teardown 使用(10) | 是否合理使用 `beforeEach`/`afterEach`/`beforeAll`/`afterAll` |
|
|
137
|
+
| 命名规范(5) | describe 名匹配 `^ModuleName$`,test/it 名匹配 `^should .+$` |
|
|
138
|
+
|
|
139
|
+
**通用规则**:
|
|
140
|
+
- 分母为 0 时(无适用项),该项给满分
|
|
141
|
+
- 超限封顶:`min(实际/阈值, 1.0)`
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 阶段四:评分计算
|
|
146
|
+
|
|
147
|
+
**输入**:覆盖率数据 + 质量检查结果
|
|
148
|
+
|
|
149
|
+
**操作**:按 `scoring-rules.md` 的评分规则计算总分
|
|
150
|
+
|
|
151
|
+
**评分公式**:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
总分 = 行覆盖率得分 + 分支覆盖率得分 + 函数覆盖率得分 + 质量维度得分
|
|
155
|
+
|
|
156
|
+
单项得分 = min(实际值/阈值, 1.0) × 满分
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**等级**:
|
|
160
|
+
|
|
161
|
+
| 等级 | 分数 |
|
|
162
|
+
|------|------|
|
|
163
|
+
| A | 90-100 |
|
|
164
|
+
| B | 80-89 |
|
|
165
|
+
| C | 60-79 |
|
|
166
|
+
| D | <60 |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 阶段五:输出结果
|
|
171
|
+
|
|
172
|
+
**输出格式**:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
## 覆盖率与质量分析报告
|
|
176
|
+
|
|
177
|
+
### 总分:XX / 100(等级:X)
|
|
178
|
+
|
|
179
|
+
### 覆盖率明细
|
|
180
|
+
| 维度 | 实际 | 阈值 | 权重 | 得分 |
|
|
181
|
+
|------|------|------|------|------|
|
|
182
|
+
| 行覆盖率 | XX% | XX% | XX | XX |
|
|
183
|
+
| 分支覆盖率 | XX% | XX% | XX | XX |
|
|
184
|
+
| 函数覆盖率 | XX% | XX% | XX | XX |
|
|
185
|
+
|
|
186
|
+
### 质量明细
|
|
187
|
+
| 维度 | 达标/应测 | 权重 | 得分 |
|
|
188
|
+
|------|----------|------|------|
|
|
189
|
+
| 断言完整性 | X/X | X | X |
|
|
190
|
+
| 异常路径覆盖 | X/X | X | X |
|
|
191
|
+
| 边界值覆盖 | X/X | X | X |
|
|
192
|
+
| 命名规范 | X/X | X | X |
|
|
193
|
+
|
|
194
|
+
### 未覆盖区域
|
|
195
|
+
| 文件 | 未覆盖函数 | 未覆盖行数 |
|
|
196
|
+
|------|-----------|-----------|
|
|
197
|
+
| src/xxx.js | funcA, funcB | 15 |
|
|
198
|
+
|
|
199
|
+
### 改进建议
|
|
200
|
+
1. 为 funcA 添加正向测试用例
|
|
201
|
+
2. 为 funcB 的 if 分支添加边界值用例
|
|
202
|
+
3. ...
|
|
203
|
+
|
|
204
|
+
### 结论
|
|
205
|
+
- 得分 XX,阈值 XX → [达标/未达标]
|
|
206
|
+
- [未达标] → 建议进入用例创建阶段
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 决策
|
|
212
|
+
|
|
213
|
+
| 条件 | 动作 |
|
|
214
|
+
|------|------|
|
|
215
|
+
| score ≥ coverage_threshold | 输出"达标",流程结束 |
|
|
216
|
+
| score < coverage_threshold | 输出未覆盖区域,交给 Step 5(按 references/case-create.md 执行) |
|
|
217
|
+
| score ≤ previous_score(非首轮) | 输出"无改进",提前退出外层 loop |
|
|
218
|
+
|
|
219
|
+
## 失败处理
|
|
220
|
+
|
|
221
|
+
| 场景 | 处理方式 |
|
|
222
|
+
|------|---------|
|
|
223
|
+
| coverage-summary.json 不存在 | 退出,提示覆盖率报告未生成 |
|
|
224
|
+
| 目标模块路径无效 | 退出,提示路径不存在 |
|
|
225
|
+
| 测试目录不存在 | 输出 0 分,提示需要创建测试目录 |
|
|
226
|
+
| 测试目录为空(无 *.test.js/*.test.ts 文件) | 输出 0 分,将全部源码文件列为未覆盖,提示需要先创建用例 |
|
|
227
|
+
| jest 超时 | 退出,提示测试执行超时,建议检查是否有 hang 住的用例或增加 timeout 配置 |
|
|
228
|
+
|
|
229
|
+
> **注意**:agent 在首轮检测到 test_dir 为空时会跳过本技能,直接进入 case-create。
|
|
230
|
+
> 此场景仅作为兜底保护,确保即使 agent 未跳过也不会崩溃。
|
|
231
|
+
|
|
232
|
+
## 一定要做
|
|
233
|
+
|
|
234
|
+
1. 必须使用传入的 test_dir 运行覆盖率分析,并根据 test_type 选择评分权重
|
|
235
|
+
2. 覆盖率数据必须来自 coverage-summary.json,不做主观判断
|
|
236
|
+
3. 质量检查必须通过文件扫描,不猜测
|
|
237
|
+
4. 分母为 0 时该项给满分(覆盖率维度和质量维度均适用)
|
|
238
|
+
5. 必须输出未覆盖区域清单(供 case-create 使用)
|
|
239
|
+
6. 非首轮时必须检查是否无改进
|
|
240
|
+
|
|
241
|
+
## 一定不要做
|
|
242
|
+
|
|
243
|
+
1. 不要混合 unit 和 integration 的覆盖率数据
|
|
244
|
+
2. 不要修改源码或测试文件
|
|
245
|
+
3. 不要跳过质量检查只看覆盖率
|
|
246
|
+
4. 不要主观判断测试质量,只做可程序化检查的判断
|
|
247
|
+
5. 不要忽略 coverage-summary.json 解析错误
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
> **原 skill**: `jstest-env-ensure`(已合并入 jstest)
|
|
2
|
+
> **适用**: 测试代理启动前的环境准备,任何需要验证 jest 运行环境的场景。
|
|
3
|
+
> **不适用**: 非 npm/pnpm 管理的 JS/TS 项目、非测试相关的环境检查。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 环境检查与配置加载
|
|
8
|
+
|
|
9
|
+
## 工作流模式
|
|
10
|
+
|
|
11
|
+
本 Skill 采用 **顺序执行** 工作流:
|
|
12
|
+
|
|
13
|
+
1. **项目检查**:验证是否为 npm/pnpm 管理的 JS/TS 项目
|
|
14
|
+
2. **依赖检查与安装**:检查依赖包,未安装则自动安装
|
|
15
|
+
3. **安装验证**:重新验证所有依赖是否可用
|
|
16
|
+
4. **jest 配置检查**:检查 jest 配置、模块系统、TypeScript 支持
|
|
17
|
+
5. **配置加载**:读取配置清单,输出给调用方
|
|
18
|
+
|
|
19
|
+
## 输入
|
|
20
|
+
|
|
21
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
22
|
+
|------|------|------|------|
|
|
23
|
+
| 无 | - | - | 自动检测当前工程 |
|
|
24
|
+
|
|
25
|
+
## 输出
|
|
26
|
+
|
|
27
|
+
- 配置对象(包含 dependencies、loops、metrics、naming、types 等字段)
|
|
28
|
+
- 环境检查报告
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 阶段一:项目检查
|
|
33
|
+
|
|
34
|
+
**操作**:
|
|
35
|
+
|
|
36
|
+
1. 检查 `package.json` 是否存在且包含 `"name"` 字段
|
|
37
|
+
2. 检查 `node_modules/` 目录是否存在
|
|
38
|
+
3. 运行 `node --version` 验证 node 可用
|
|
39
|
+
|
|
40
|
+
**决策**:
|
|
41
|
+
|
|
42
|
+
| 条件 | 动作 |
|
|
43
|
+
|------|------|
|
|
44
|
+
| package.json 存在且 node_modules 存在 | 进入阶段二 |
|
|
45
|
+
| package.json 不存在 | **直接退出**,提示"当前 agent 仅支持 npm/pnpm 项目,未找到 package.json" |
|
|
46
|
+
| node_modules 不存在 | **直接退出**,提示"当前 agent 仅支持 npm/pnpm 项目,未找到 node_modules 目录,请先运行 npm install 或 pnpm install" |
|
|
47
|
+
| node --version 失败 | **直接退出**,提示"node 不可用,请先安装 Node.js" |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 阶段二:依赖检查与安装
|
|
52
|
+
|
|
53
|
+
**输入**:读取 `config.md` 的 dependencies 清单
|
|
54
|
+
|
|
55
|
+
**操作**:
|
|
56
|
+
|
|
57
|
+
1. 逐个执行 `check` 命令验证是否已安装
|
|
58
|
+
2. 对未安装的依赖,执行 `install` 命令
|
|
59
|
+
3. 安装失败 → 重试(最多 3 次,由 config 的 `env.install_retry` 控制)
|
|
60
|
+
4. `install` 为 null 的依赖(如 node)→ 跳过安装,仅检查
|
|
61
|
+
|
|
62
|
+
**包管理器检测**:
|
|
63
|
+
|
|
64
|
+
- 检查 `pnpm-lock.yaml` 存在 → 使用 `pnpm` 命令
|
|
65
|
+
- 检查 `package-lock.json` 存在 → 使用 `npm` 命令
|
|
66
|
+
- 检查 `yarn.lock` 存在 → 使用 `yarn` 命令
|
|
67
|
+
- 都不存在 → 默认使用 `npm`
|
|
68
|
+
|
|
69
|
+
**重试逻辑**:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
for each dependency:
|
|
73
|
+
if check passes:
|
|
74
|
+
mark as installed
|
|
75
|
+
else if install is null:
|
|
76
|
+
mark as missing (system-level, cannot auto-install)
|
|
77
|
+
else:
|
|
78
|
+
retry_count = 0
|
|
79
|
+
while retry_count < install_retry:
|
|
80
|
+
run install command (pnpm add -D <pkg> or npm install --save-dev <pkg>)
|
|
81
|
+
if check passes:
|
|
82
|
+
mark as installed
|
|
83
|
+
break
|
|
84
|
+
retry_count += 1
|
|
85
|
+
if still not installed:
|
|
86
|
+
mark as failed
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**决策**:
|
|
90
|
+
|
|
91
|
+
| 条件 | 动作 |
|
|
92
|
+
|------|------|
|
|
93
|
+
| 全部已安装 | 进入阶段三 |
|
|
94
|
+
| 有 required 依赖安装失败 | **直接退出**,列出失败的依赖 |
|
|
95
|
+
| 有非 required 依赖安装失败 | 记录警告,继续 |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 阶段三:安装验证
|
|
100
|
+
|
|
101
|
+
**操作**:对所有依赖重新执行 `check` 命令
|
|
102
|
+
|
|
103
|
+
**决策**:
|
|
104
|
+
|
|
105
|
+
| 条件 | 动作 |
|
|
106
|
+
|------|------|
|
|
107
|
+
| 全部通过 | 进入阶段四 |
|
|
108
|
+
| 有 required 依赖未通过 | **直接退出**,列出未通过的依赖 |
|
|
109
|
+
| 有非 required 依赖未通过 | 记录警告,继续 |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 阶段四:jest 配置检查
|
|
114
|
+
|
|
115
|
+
**操作**:
|
|
116
|
+
|
|
117
|
+
1. 检查 jest 配置来源:
|
|
118
|
+
- `package.json` 的 `"jest"` 字段是否存在
|
|
119
|
+
- `jest.config.js` 是否存在
|
|
120
|
+
- `jest.config.cjs` 是否存在
|
|
121
|
+
- `jest.config.mjs` 是否存在
|
|
122
|
+
- `jest.config.ts` 是否存在
|
|
123
|
+
2. 模块系统检测:
|
|
124
|
+
- 读取 `package.json` 的 `"type"` 字段
|
|
125
|
+
- `"type": "module"` → ESM 项目,运行 jest 需加 `--experimental-vm-modules` 标志
|
|
126
|
+
- 无 `"type"` 字段或 `"type": "commonjs"` → CommonJS 项目
|
|
127
|
+
3. TypeScript 检测:
|
|
128
|
+
- 检查 `tsconfig.json` 是否存在
|
|
129
|
+
- 若存在 → 检查 jest transform 配置(`ts-jest`、`@swc/jest`、`babel-jest` with `@babel/preset-typescript`)
|
|
130
|
+
- 若 transform 未配置 → 记录警告,提示"检测到 TypeScript 项目但未配置 jest transform,测试可能失败"
|
|
131
|
+
|
|
132
|
+
**决策**:
|
|
133
|
+
|
|
134
|
+
| 条件 | 动作 |
|
|
135
|
+
|------|------|
|
|
136
|
+
| jest 配置存在 | 进入阶段五 |
|
|
137
|
+
| jest 配置不存在 | 记录警告,提示"未找到 jest 配置,将使用默认配置" |
|
|
138
|
+
| ESM 项目未配置 transform | 记录警告,提示"ESM 项目运行 jest 需要 --experimental-vm-modules" |
|
|
139
|
+
| TypeScript 项目未配置 transform | 记录警告,提示"TypeScript 项目需要配置 jest transform" |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 阶段五:配置加载
|
|
144
|
+
|
|
145
|
+
**操作**:
|
|
146
|
+
|
|
147
|
+
1. 读取 `config.md`
|
|
148
|
+
2. 解析配置项:dependencies、env、loops、metrics(unit + integration)、naming、types
|
|
149
|
+
3. 输出配置对象给调用方(agent)
|
|
150
|
+
|
|
151
|
+
**输出格式**:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
## 环境检查报告
|
|
155
|
+
|
|
156
|
+
### 项目检查
|
|
157
|
+
- package.json: ✓
|
|
158
|
+
- node_modules: ✓
|
|
159
|
+
- node: ✓ (vXX.X.X)
|
|
160
|
+
|
|
161
|
+
### 依赖检查
|
|
162
|
+
| 依赖 | 状态 | 备注 |
|
|
163
|
+
|------|------|------|
|
|
164
|
+
| node | ✓ 已安装 | 系统级 |
|
|
165
|
+
| jest | ✓ 已安装 | - |
|
|
166
|
+
| supertest | ✗ 未安装 | 可选,跳过 |
|
|
167
|
+
|
|
168
|
+
### jest 配置检查
|
|
169
|
+
- 配置来源: package.json "jest" 字段 / jest.config.js / jest.config.cjs
|
|
170
|
+
- 模块系统: ESM / CommonJS
|
|
171
|
+
- TypeScript: ✓ (ts-jest) / ✗ (非 TS 项目)
|
|
172
|
+
- 运行命令: node --experimental-vm-modules node_modules/jest/bin/jest.js --no-cache (ESM)
|
|
173
|
+
npx jest --no-cache (CommonJS)
|
|
174
|
+
|
|
175
|
+
### 配置已加载
|
|
176
|
+
- coverage_threshold: 90 (unit) / 70 (integration)
|
|
177
|
+
- outer_max: 3
|
|
178
|
+
- inner_max: 3
|
|
179
|
+
- test_root: tests
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 失败处理
|
|
185
|
+
|
|
186
|
+
| 场景 | 处理方式 |
|
|
187
|
+
|------|---------|
|
|
188
|
+
| 非 npm/pnpm 项目 | 直接退出,提示仅支持 npm/pnpm 项目 |
|
|
189
|
+
| required 依赖安装失败(重试 3 次) | 退出,列出失败依赖 |
|
|
190
|
+
| required 依赖验证不通过 | 退出,列出未通过依赖 |
|
|
191
|
+
| config.md 不存在或格式错误 | 退出,提示配置文件缺失 |
|
|
192
|
+
| 非项目特定错误 | 记录警告,不阻断流程 |
|
|
193
|
+
|
|
194
|
+
## 一定要做
|
|
195
|
+
|
|
196
|
+
1. 必须先检查 npm/pnpm 项目结构,不满足直接退出
|
|
197
|
+
2. 依赖检查必须读取 config.md 的 dependencies 清单
|
|
198
|
+
3. 安装失败必须重试,重试次数由 config 控制
|
|
199
|
+
4. 安装后必须重新验证
|
|
200
|
+
5. 必须检查 jest 配置、模块系统和 TypeScript 支持
|
|
201
|
+
6. 最终输出完整的配置对象给调用方
|
|
202
|
+
|
|
203
|
+
## 一定不要做
|
|
204
|
+
|
|
205
|
+
1. 不要跳过 npm/pnpm 项目检查
|
|
206
|
+
2. 不要安装 install 为 null 的依赖(系统级工具)
|
|
207
|
+
3. 不要忽略 required 依赖的失败
|
|
208
|
+
4. 不要修改 config.md 文件内容
|
|
209
|
+
5. 不要预设任何项目特定的依赖或配置
|
|
210
|
+
6. 不要修改 jest 配置文件(除非直接导致失败)
|