dev-playbooks-cn 1.0.0
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/LICENSE +21 -0
- package/README.md +466 -0
- package/bin/devbooks.js +987 -0
- package/package.json +43 -0
- package/skills/Skills/344/275/277/347/224/250/350/257/264/346/230/216.md +446 -0
- package/skills/Skill/345/274/200/345/217/221/346/214/207/345/215/227.md +248 -0
- package/skills/_shared/context-detection-template.md +315 -0
- package/skills/_shared/mcp-enhancement-template.md +144 -0
- package/skills/_shared/references//351/200/232/347/224/250/345/256/210/351/227/250/345/215/217/350/256/256.md +114 -0
- package/skills/_template/config-discovery-template.md +126 -0
- package/skills/devbooks-brownfield-bootstrap/SKILL.md +167 -0
- package/skills/devbooks-brownfield-bootstrap/references//344/273/243/347/240/201/345/257/274/350/210/252/347/255/226/347/225/245.md +203 -0
- package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226.md +96 -0
- package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226/346/217/220/347/244/272/350/257/215.md +115 -0
- package/skills/devbooks-brownfield-bootstrap/references//346/234/257/350/257/255/350/241/250/346/250/241/346/235/277.md +42 -0
- package/skills/devbooks-brownfield-bootstrap/scripts/cod-update.sh +357 -0
- package/skills/devbooks-brownfield-bootstrap/templates/project-profile-template.md +172 -0
- package/skills/devbooks-c4-map/SKILL.md +151 -0
- package/skills/devbooks-c4-map/references/C4/346/236/266/346/236/204/345/234/260/345/233/276/346/217/220/347/244/272/350/257/215.md +33 -0
- package/skills/devbooks-c4-map/references//345/210/206/345/261/202/347/272/246/346/235/237/346/243/200/346/237/245/346/270/205/345/215/225.md +185 -0
- package/skills/devbooks-code-review/SKILL.md +175 -0
- package/skills/devbooks-code-review/references/PR/346/250/241/346/235/277/344/270/216/346/214/207/345/215/227.md +321 -0
- package/skills/devbooks-code-review/references//344/273/243/347/240/201/350/257/204/345/256/241/346/217/220/347/244/272/350/257/215.md +100 -0
- package/skills/devbooks-code-review/references//345/235/217/345/221/263/351/201/223/351/200/237/346/237/245/350/241/250.md +495 -0
- package/skills/devbooks-code-review/references//350/265/204/346/272/220/347/256/241/347/220/206/345/256/241/346/237/245/346/270/205/345/215/225.md +311 -0
- package/skills/devbooks-coder/SKILL.md +219 -0
- package/skills/devbooks-coder/references//344/273/243/347/240/201/345/256/236/347/216/260/346/217/220/347/244/272/350/257/215.md +70 -0
- package/skills/devbooks-coder/references//344/275/216/351/243/216/351/231/251/346/224/271/345/212/250/346/212/200/346/234/257.md +275 -0
- package/skills/devbooks-coder/references//346/227/245/345/277/227/350/247/204/350/214/203.md +329 -0
- package/skills/devbooks-coder/references//347/274/226/347/240/201/351/243/216/346/240/274/347/273/206/345/210/231.md +351 -0
- package/skills/devbooks-coder/references//351/224/231/350/257/257/347/240/201/350/247/204/350/214/203.md +463 -0
- package/skills/devbooks-delivery-workflow/SKILL.md +217 -0
- package/skills/devbooks-delivery-workflow/references//344/272/244/344/273/230/351/252/214/346/224/266/345/267/245/344/275/234/346/265/201.md +256 -0
- package/skills/devbooks-delivery-workflow/references//345/216/237/345/236/213-/347/224/237/344/272/247/345/217/214/350/275/250/346/250/241/345/274/217.md +168 -0
- package/skills/devbooks-delivery-workflow/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +133 -0
- package/skills/devbooks-delivery-workflow/scripts/ac-trace-check.sh +330 -0
- package/skills/devbooks-delivery-workflow/scripts/audit-scope.sh +262 -0
- package/skills/devbooks-delivery-workflow/scripts/change-check.sh +1040 -0
- package/skills/devbooks-delivery-workflow/scripts/change-codemod-scaffold.sh +135 -0
- package/skills/devbooks-delivery-workflow/scripts/change-evidence.sh +152 -0
- package/skills/devbooks-delivery-workflow/scripts/change-scaffold.sh +442 -0
- package/skills/devbooks-delivery-workflow/scripts/change-spec-delta-scaffold.sh +136 -0
- package/skills/devbooks-delivery-workflow/scripts/constitution-check.sh +237 -0
- package/skills/devbooks-delivery-workflow/scripts/env-match-check.sh +128 -0
- package/skills/devbooks-delivery-workflow/scripts/fitness-check.sh +387 -0
- package/skills/devbooks-delivery-workflow/scripts/guardrail-check.sh +519 -0
- package/skills/devbooks-delivery-workflow/scripts/handoff-check.sh +141 -0
- package/skills/devbooks-delivery-workflow/scripts/hygiene-check.sh +340 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-from-openspec.sh +385 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-to-v2-gates.sh +202 -0
- package/skills/devbooks-delivery-workflow/scripts/progress-dashboard.sh +319 -0
- package/skills/devbooks-delivery-workflow/scripts/prototype-promote.sh +341 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-preview.sh +203 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-promote.sh +118 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-rollback.sh +124 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-stage.sh +117 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-all.sh +78 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-npm-package.sh +123 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-openspec-free.sh +81 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-slash-commands.sh +146 -0
- package/skills/devbooks-delivery-workflow/templates/handoff.md +50 -0
- package/skills/devbooks-design-backport/SKILL.md +73 -0
- package/skills/devbooks-design-backport/references//345/233/236/345/206/231/350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +196 -0
- package/skills/devbooks-design-doc/SKILL.md +121 -0
- package/skills/devbooks-design-doc/references//345/276/256/346/234/215/345/212/241/350/256/276/350/256/241/346/270/205/345/215/225.md +149 -0
- package/skills/devbooks-design-doc/references//350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +189 -0
- package/skills/devbooks-design-doc/references//351/232/220/347/247/201/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +240 -0
- package/skills/devbooks-entropy-monitor/SKILL.md +188 -0
- package/skills/devbooks-entropy-monitor/references//347/206/265/345/272/246/351/207/217/346/226/271/346/263/225/350/256/272.md +223 -0
- package/skills/devbooks-entropy-monitor/scripts/entropy-measure.sh +449 -0
- package/skills/devbooks-entropy-monitor/scripts/entropy-report.sh +303 -0
- package/skills/devbooks-entropy-monitor/templates/thresholds.json +99 -0
- package/skills/devbooks-federation/SKILL.md +264 -0
- package/skills/devbooks-federation/scripts/federation-check.sh +144 -0
- package/skills/devbooks-federation/templates/federation.yaml +89 -0
- package/skills/devbooks-impact-analysis/SKILL.md +135 -0
- package/skills/devbooks-impact-analysis/references//345/275/261/345/223/215/345/210/206/346/236/220/346/217/220/347/244/272/350/257/215.md +82 -0
- package/skills/devbooks-impact-analysis/scripts/graph-cache.sh +214 -0
- package/skills/devbooks-implementation-plan/SKILL.md +83 -0
- package/skills/devbooks-implementation-plan/references//347/274/226/347/240/201/350/256/241/345/210/222/346/217/220/347/244/272/350/257/215.md +99 -0
- package/skills/devbooks-index-bootstrap/SKILL.md +240 -0
- package/skills/devbooks-proposal-author/SKILL.md +83 -0
- package/skills/devbooks-proposal-author/references//346/217/220/346/241/210/346/222/260/345/206/231/346/217/220/347/244/272/350/257/215.md +66 -0
- package/skills/devbooks-proposal-challenger/SKILL.md +86 -0
- package/skills/devbooks-proposal-challenger/references//344/274/246/347/220/206/344/270/216/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +176 -0
- package/skills/devbooks-proposal-challenger/references//346/217/220/346/241/210/350/264/250/347/226/221/346/217/220/347/244/272/350/257/215.md +57 -0
- package/skills/devbooks-proposal-debate-workflow/SKILL.md +78 -0
- package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/345/267/245/344/275/234/346/265/201.md +24 -0
- package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/346/250/241/346/235/277.md +35 -0
- package/skills/devbooks-proposal-debate-workflow/scripts/proposal-debate-check.sh +102 -0
- package/skills/devbooks-proposal-judge/SKILL.md +78 -0
- package/skills/devbooks-proposal-judge/references//346/217/220/346/241/210/350/243/201/345/206/263/346/217/220/347/244/272/350/257/215.md +37 -0
- package/skills/devbooks-router/SKILL.md +346 -0
- package/skills/devbooks-spec-contract/SKILL.md +191 -0
- package/skills/devbooks-spec-contract/references/API/350/256/276/350/256/241/346/214/207/345/215/227.md +349 -0
- package/skills/devbooks-spec-contract/references//345/245/221/347/272/246/344/270/216/346/225/260/346/215/256/345/256/232/344/271/211/346/217/220/347/244/272/350/257/215.md +85 -0
- package/skills/devbooks-spec-contract/references//350/247/204/346/240/274/345/217/230/346/233/264/346/217/220/347/244/272/350/257/215.md +63 -0
- package/skills/devbooks-spec-contract/references//351/232/220/345/274/217/345/217/230/346/233/264/346/243/200/346/265/213/346/217/220/347/244/272/350/257/215.md +183 -0
- package/skills/devbooks-spec-contract/scripts/implicit-change-detect.sh +378 -0
- package/skills/devbooks-spec-gardener/SKILL.md +72 -0
- package/skills/devbooks-spec-gardener/references//350/247/204/346/240/274/345/233/255/344/270/201/346/217/220/347/244/272/350/257/215.md +41 -0
- package/skills/devbooks-test-owner/SKILL.md +172 -0
- package/skills/devbooks-test-owner/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +228 -0
- package/skills/devbooks-test-owner/references//345/274/202/346/255/245/347/263/273/347/273/237/346/265/213/350/257/225/347/255/226/347/225/245.md +316 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/344/273/243/347/240/201/346/217/220/347/244/272/350/257/215.md +208 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/345/210/206/345/261/202/347/255/226/347/225/245.md +281 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/351/251/261/345/212/250.md +394 -0
- package/skills/devbooks-test-owner/references//350/247/243/344/276/235/350/265/226/346/212/200/346/234/257/351/200/237/346/237/245/350/241/250.md +432 -0
- package/skills/devbooks-test-reviewer/SKILL.md +189 -0
- package/templates/.devbooks/config.yaml +88 -0
- package/templates/claude-commands/devbooks/apply.md +38 -0
- package/templates/claude-commands/devbooks/archive.md +33 -0
- package/templates/claude-commands/devbooks/backport.md +19 -0
- package/templates/claude-commands/devbooks/bootstrap.md +19 -0
- package/templates/claude-commands/devbooks/c4.md +19 -0
- package/templates/claude-commands/devbooks/challenger.md +19 -0
- package/templates/claude-commands/devbooks/code.md +19 -0
- package/templates/claude-commands/devbooks/debate.md +19 -0
- package/templates/claude-commands/devbooks/delivery.md +19 -0
- package/templates/claude-commands/devbooks/design.md +19 -0
- package/templates/claude-commands/devbooks/entropy.md +19 -0
- package/templates/claude-commands/devbooks/federation.md +19 -0
- package/templates/claude-commands/devbooks/gardener.md +19 -0
- package/templates/claude-commands/devbooks/impact.md +19 -0
- package/templates/claude-commands/devbooks/index.md +19 -0
- package/templates/claude-commands/devbooks/judge.md +19 -0
- package/templates/claude-commands/devbooks/plan.md +19 -0
- package/templates/claude-commands/devbooks/proposal.md +19 -0
- package/templates/claude-commands/devbooks/quick.md +42 -0
- package/templates/claude-commands/devbooks/review.md +19 -0
- package/templates/claude-commands/devbooks/router.md +19 -0
- package/templates/claude-commands/devbooks/spec.md +19 -0
- package/templates/claude-commands/devbooks/test-review.md +19 -0
- package/templates/claude-commands/devbooks/test.md +19 -0
- package/templates/dev-playbooks/README.md +458 -0
- package/templates/dev-playbooks/changes/.gitkeep +1 -0
- package/templates/dev-playbooks/constitution.md +116 -0
- package/templates/dev-playbooks/project.md +96 -0
- package/templates/dev-playbooks/scripts/.gitkeep +1 -0
- package/templates/dev-playbooks/specs/_meta/anti-patterns/.gitkeep +2 -0
- package/templates/dev-playbooks/specs/_meta/glossary.md +47 -0
- package/templates/dev-playbooks/specs/_meta/project-profile.md +79 -0
- package/templates/dev-playbooks/specs/architecture/fitness-rules.md +95 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# verification.md 模板(变更包内)
|
|
2
|
+
|
|
3
|
+
> 推荐路径:`<change-root>/<change-id>/verification.md`
|
|
4
|
+
>
|
|
5
|
+
> 目标:把“完成定义”落到可执行锚点与证据上,并提供 `AC-xxx -> Requirement/Scenario -> Test IDs -> Evidence` 的追溯。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 元信息
|
|
10
|
+
|
|
11
|
+
- Change ID:`<change-id>`
|
|
12
|
+
- 状态:`Draft | Ready | Done | Archived`
|
|
13
|
+
- 关联:
|
|
14
|
+
- Proposal:`<change-root>/<change-id>/proposal.md`
|
|
15
|
+
- Design:`<change-root>/<change-id>/design.md`
|
|
16
|
+
- Tasks:`<change-root>/<change-id>/tasks.md`
|
|
17
|
+
- Spec deltas:`<change-root>/<change-id>/specs/**`
|
|
18
|
+
- 维护者:`<you>`
|
|
19
|
+
- 更新时间:`YYYY-MM-DD`
|
|
20
|
+
- Test Owner(独立对话):`<session/agent>`
|
|
21
|
+
- Coder(独立对话):`<session/agent>`
|
|
22
|
+
- Red 基线证据:`<change-root>/<change-id>/evidence/`
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
========================
|
|
27
|
+
A) 测试计划指令表
|
|
28
|
+
========================
|
|
29
|
+
|
|
30
|
+
### 主线计划区 (Main Plan Area)
|
|
31
|
+
|
|
32
|
+
- [ ] TP1.1 `<一句话目标>`
|
|
33
|
+
- Why:
|
|
34
|
+
- Acceptance Criteria(引用 AC-xxx / Requirement):
|
|
35
|
+
- Test Type:`unit | contract | integration | e2e | fitness | static`
|
|
36
|
+
- Non-goals:
|
|
37
|
+
- Candidate Anchors(Test IDs / commands / evidence):
|
|
38
|
+
|
|
39
|
+
### 临时计划区 (Temporary Plan Area)
|
|
40
|
+
|
|
41
|
+
- (留空/按需)
|
|
42
|
+
|
|
43
|
+
### 断点区 (Context Switch Breakpoint Area)
|
|
44
|
+
|
|
45
|
+
- 上次进度:
|
|
46
|
+
- 当前阻塞:
|
|
47
|
+
- 下一步最短路径:
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
========================
|
|
52
|
+
B) 追溯矩阵(Traceability Matrix)
|
|
53
|
+
========================
|
|
54
|
+
|
|
55
|
+
> 建议按 AC-xxx 为主键;如果你维护了 Requirements/Scenarios 规格条目,可同时列出对应项。
|
|
56
|
+
>
|
|
57
|
+
> **追溯完整性要求**:每个 AC 必须能追溯到完整链条 `AC → Requirement/Scenario → Test IDs → Evidence`。
|
|
58
|
+
|
|
59
|
+
| AC | Requirement/Scenario | Test IDs / Commands | Evidence / MANUAL-* | Status | 因果链完整性 |
|
|
60
|
+
|---|---|---|---|---|---|
|
|
61
|
+
| AC-001 | `<capability>/Requirement...` | `TEST-...` / `pnpm test ...` | `MANUAL-001` / link | TODO | [ ] 完整 |
|
|
62
|
+
|
|
63
|
+
### 追溯矩阵完整性检查清单
|
|
64
|
+
|
|
65
|
+
- [ ] **无孤儿 AC**:每个 AC 都有对应的 Test IDs 或 MANUAL-* 条目
|
|
66
|
+
- [ ] **无孤儿测试**:每个 Test ID 都能追溯到 AC 或 Requirement
|
|
67
|
+
- [ ] **无无证据 DONE**:每个 Status=DONE 的条目都有 Evidence 链接
|
|
68
|
+
- [ ] **Red 基线存在**:`evidence/` 目录包含初始失败证据(证明测试有效)
|
|
69
|
+
- [ ] **Green 证据存在**:`evidence/` 目录包含最终通过证据
|
|
70
|
+
|
|
71
|
+
### 追溯链示例
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
AC-001 (design.md)
|
|
75
|
+
├── Requirement: REQ-ORDER-001 (specs/order-query/spec.md)
|
|
76
|
+
│ └── Scenario: SC-001 "分页参数非法时返回 400"
|
|
77
|
+
├── Test IDs:
|
|
78
|
+
│ ├── TEST-001-a: unit test (tests/unit/order_test.py::test_invalid_page)
|
|
79
|
+
│ └── TEST-001-b: contract test (tests/contract/order_api_test.py::test_400)
|
|
80
|
+
└── Evidence:
|
|
81
|
+
├── Red: evidence/red-baseline-2024-01-05.log
|
|
82
|
+
└── Green: evidence/green-final-2024-01-06.log
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
========================
|
|
88
|
+
C) 执行锚点(Deterministic Anchors)
|
|
89
|
+
========================
|
|
90
|
+
|
|
91
|
+
### 1) 行为(Behavior)
|
|
92
|
+
|
|
93
|
+
- unit:
|
|
94
|
+
- integration:
|
|
95
|
+
- e2e:
|
|
96
|
+
|
|
97
|
+
### 2) 契约(Contract)
|
|
98
|
+
|
|
99
|
+
- OpenAPI/Proto/Schema:
|
|
100
|
+
- contract tests:
|
|
101
|
+
|
|
102
|
+
### 3) 结构(Structure / Fitness Functions)
|
|
103
|
+
|
|
104
|
+
- 分层/依赖方向/禁止循环:
|
|
105
|
+
|
|
106
|
+
### 4) 静态与安全(Static/Security)
|
|
107
|
+
|
|
108
|
+
- lint/typecheck/build:
|
|
109
|
+
- SAST/secret scan:
|
|
110
|
+
- 报告格式:`json|xml`(优先机器可读)
|
|
111
|
+
- 质量闸门:复杂度/重复度/依赖规则(如有)
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
========================
|
|
116
|
+
D) MANUAL-* 清单(人工/混合验收)
|
|
117
|
+
========================
|
|
118
|
+
|
|
119
|
+
> 只收录“无法稳定自动化”的验收项;每条必须写清证据要求。
|
|
120
|
+
|
|
121
|
+
- [ ] MANUAL-001 `<验收项>`
|
|
122
|
+
- Pass/Fail 判据:
|
|
123
|
+
- Evidence(截图/录像/链接/日志):
|
|
124
|
+
- 责任人/签字:
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
========================
|
|
129
|
+
E) 风险与降级(可选)
|
|
130
|
+
========================
|
|
131
|
+
|
|
132
|
+
- 风险:
|
|
133
|
+
- 降级策略:
|
|
134
|
+
- 回滚策略:
|
|
135
|
+
|
|
136
|
+
========================
|
|
137
|
+
F) 结构质量守门记录(可选)
|
|
138
|
+
========================
|
|
139
|
+
|
|
140
|
+
> 若本次变更涉及“代理指标驱动”的要求或潜在结构风险,请记录决策与替代闸门。
|
|
141
|
+
|
|
142
|
+
- 冲突点:
|
|
143
|
+
- 评估影响(内聚/耦合/可测试性):
|
|
144
|
+
- 替代闸门(复杂度/耦合/依赖方向/测试质量):
|
|
145
|
+
- 决策与授权:
|
|
146
|
+
|
|
147
|
+
========================
|
|
148
|
+
G) 价值流与度量(可选,但必须显式填"无")
|
|
149
|
+
========================
|
|
150
|
+
|
|
151
|
+
> 目的:把"交付更快/更稳/更有价值"的判断落到可观测口径;避免只看局部写码速度。
|
|
152
|
+
|
|
153
|
+
- 目标价值信号:`<填"无"或写明指标/看板/日志/业务事件>`
|
|
154
|
+
- 价值流瓶颈假设(哪里会堵):`<填"无"或写明 PR review / tests / 发布 / 手工验收 的排队点>`
|
|
155
|
+
- 交付与稳定性指标(可选 DORA):`<填"无"或写明 Lead Time / Deploy Frequency / Change Failure Rate / MTTR 的观测口径>`
|
|
156
|
+
- 观测窗口与触发点:`<填"无"或写明上线后多久、观察哪些告警/报表>`
|
|
157
|
+
- Evidence:`<填"无"或写明链接/截图/报表路径(建议落到 evidence/)>`
|
|
158
|
+
|
|
159
|
+
========================
|
|
160
|
+
H) 审计与证据管理(推荐)
|
|
161
|
+
========================
|
|
162
|
+
|
|
163
|
+
> 目的:确保变更过程可追溯、可审计,满足合规要求。
|
|
164
|
+
|
|
165
|
+
### 证据目录结构
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
<change-root>/<change-id>/evidence/
|
|
169
|
+
├── red-baseline/ # Red 基线证据(必须)
|
|
170
|
+
│ ├── test-failures-<timestamp>.log
|
|
171
|
+
│ └── test-failures-<timestamp>.json
|
|
172
|
+
├── green-final/ # Green 最终证据(必须)
|
|
173
|
+
│ ├── test-results-<timestamp>.log
|
|
174
|
+
│ └── test-results-<timestamp>.json
|
|
175
|
+
├── performance/ # 性能测试证据(如有)
|
|
176
|
+
│ └── benchmark-<timestamp>.json
|
|
177
|
+
├── manual-acceptance/ # 人工验收证据(如有)
|
|
178
|
+
│ ├── MANUAL-001-screenshot.png
|
|
179
|
+
│ └── MANUAL-001-signoff.md
|
|
180
|
+
└── audit-log.md # 审计日志(推荐)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 审计日志模板(audit-log.md)
|
|
184
|
+
|
|
185
|
+
```markdown
|
|
186
|
+
# 变更审计日志
|
|
187
|
+
|
|
188
|
+
## 元信息
|
|
189
|
+
- Change ID: <change-id>
|
|
190
|
+
- 创建时间: YYYY-MM-DD HH:MM
|
|
191
|
+
- Test Owner: <name/session>
|
|
192
|
+
- Coder: <name/session>
|
|
193
|
+
|
|
194
|
+
## 关键事件记录
|
|
195
|
+
|
|
196
|
+
| 时间 | 事件 | 操作者 | 证据链接 |
|
|
197
|
+
|------|------|--------|----------|
|
|
198
|
+
| YYYY-MM-DD HH:MM | Red 基线建立 | Test Owner | evidence/red-baseline/xxx.log |
|
|
199
|
+
| YYYY-MM-DD HH:MM | 首次 Green | Coder | evidence/green-final/xxx.log |
|
|
200
|
+
| YYYY-MM-DD HH:MM | 人工验收签核 | Reviewer | evidence/manual-acceptance/xxx.md |
|
|
201
|
+
|
|
202
|
+
## 变更决策记录
|
|
203
|
+
|
|
204
|
+
| 时间 | 决策内容 | 原因 | 影响范围 |
|
|
205
|
+
|------|----------|------|----------|
|
|
206
|
+
| YYYY-MM-DD | 调整 AC-002 验收标准 | 发现边界条件遗漏 | tests/unit/xxx_test.py |
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 证据采集命令(推荐使用脚本)
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# 采集 Red 基线
|
|
213
|
+
change-evidence.sh <change-id> --label red-baseline --project-root "$(pwd)" --change-root <change-root> -- <test-command>
|
|
214
|
+
|
|
215
|
+
# 采集 Green 最终结果
|
|
216
|
+
change-evidence.sh <change-id> --label green-final --project-root "$(pwd)" --change-root <change-root> -- <test-command>
|
|
217
|
+
|
|
218
|
+
# 采集性能测试结果
|
|
219
|
+
change-evidence.sh <change-id> --label performance --project-root "$(pwd)" --change-root <change-root> -- <benchmark-command>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 审计完整性检查清单
|
|
223
|
+
|
|
224
|
+
- [ ] **Red 基线存在**:`evidence/red-baseline/` 有失败日志
|
|
225
|
+
- [ ] **Green 证据存在**:`evidence/green-final/` 有通过日志
|
|
226
|
+
- [ ] **时间戳可追溯**:证据文件名包含时间戳
|
|
227
|
+
- [ ] **审计日志完整**:`audit-log.md` 记录关键事件
|
|
228
|
+
- [ ] **人工验收有签核**:MANUAL-* 条目有责任人签字
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# 异步系统测试策略
|
|
2
|
+
|
|
3
|
+
> 适用场景:测试涉及消息队列、事件驱动、最终一致性、分布式事务的系统时,使用本清单设计测试策略。
|
|
4
|
+
>
|
|
5
|
+
> 本文档为**可选参考**,仅当项目涉及异步/事件驱动架构时使用。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1) 异步系统的测试挑战
|
|
10
|
+
|
|
11
|
+
### 1.1 核心难点
|
|
12
|
+
|
|
13
|
+
| 挑战 | 描述 | 测试策略 |
|
|
14
|
+
|------|------|----------|
|
|
15
|
+
| 非确定性时序 | 消息到达顺序不确定 | 使用显式等待 + 超时,避免 sleep |
|
|
16
|
+
| 最终一致性 | 系统状态需要时间收敛 | 轮询验证 + 明确收敛条件 |
|
|
17
|
+
| 幂等性验证 | 重复消息不应产生重复副作用 | 发送相同消息多次,验证结果一致 |
|
|
18
|
+
| 故障注入困难 | 网络分区、消息丢失难以模拟 | 使用可控的测试替身(Test Double) |
|
|
19
|
+
| 状态散布 | 状态分布在多个服务/存储中 | 定义清晰的"系统状态快照"方法 |
|
|
20
|
+
|
|
21
|
+
### 1.2 测试金字塔调整
|
|
22
|
+
|
|
23
|
+
异步系统的测试金字塔与同步系统不同:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
/\
|
|
27
|
+
/ \ E2E(最小化,只验证关键链路)
|
|
28
|
+
/----\
|
|
29
|
+
/ \ Contract Tests(重点:消息契约)
|
|
30
|
+
/--------\
|
|
31
|
+
/ \ Integration Tests(重点:消息处理逻辑)
|
|
32
|
+
/------------\
|
|
33
|
+
/ \ Unit Tests(纯逻辑,无 IO)
|
|
34
|
+
/----------------\
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**关键差异**:
|
|
38
|
+
- Contract Tests 更重要:验证消息格式、事件信封、schema 兼容性
|
|
39
|
+
- Integration Tests 需要覆盖:超时、重试、幂等、乱序处理
|
|
40
|
+
- E2E Tests 要谨慎:异步系统的 E2E 容易产生 Flaky Tests
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 2) 最终一致性测试
|
|
45
|
+
|
|
46
|
+
### 2.1 测试模式:轮询等待(Polling)
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
# 推荐模式:显式轮询 + 超时
|
|
50
|
+
def wait_for_eventual_consistency(
|
|
51
|
+
condition_fn, # 返回 True 表示状态已收敛
|
|
52
|
+
timeout_ms=5000, # 最大等待时间
|
|
53
|
+
poll_interval_ms=100 # 轮询间隔
|
|
54
|
+
):
|
|
55
|
+
start = time.now()
|
|
56
|
+
while time.now() - start < timeout_ms:
|
|
57
|
+
if condition_fn():
|
|
58
|
+
return True
|
|
59
|
+
sleep(poll_interval_ms)
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
# 示例:等待订单状态同步到查询服务
|
|
63
|
+
assert wait_for_eventual_consistency(
|
|
64
|
+
lambda: query_service.get_order(order_id).status == "PAID",
|
|
65
|
+
timeout_ms=3000
|
|
66
|
+
)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2.2 测试检查清单
|
|
70
|
+
|
|
71
|
+
- [ ] 定义"状态收敛"的明确条件(不是"等 N 秒")
|
|
72
|
+
- [ ] 设置合理的超时时间(不要太短导致 Flaky,不要太长拖慢测试)
|
|
73
|
+
- [ ] 测试覆盖"收敛失败"场景(超时后系统行为是什么?)
|
|
74
|
+
- [ ] 验证中间状态是否可接受(最终一致性过程中用户看到什么?)
|
|
75
|
+
|
|
76
|
+
### 2.3 design.md 应声明
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
### 最终一致性约束
|
|
80
|
+
- 一致性窗口:< 5 秒(99% 场景)
|
|
81
|
+
- 中间状态用户可见行为:显示"处理中"
|
|
82
|
+
- 收敛失败处理:触发补偿/告警
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 3) 幂等性测试
|
|
88
|
+
|
|
89
|
+
### 3.1 幂等性测试模式
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# 测试:同一消息消费 N 次,副作用只产生 1 次
|
|
93
|
+
def test_idempotent_message_processing():
|
|
94
|
+
message_id = "msg-001"
|
|
95
|
+
order_id = "order-001"
|
|
96
|
+
|
|
97
|
+
# 发送相同消息 3 次
|
|
98
|
+
for _ in range(3):
|
|
99
|
+
send_message(CreateOrderEvent(
|
|
100
|
+
message_id=message_id,
|
|
101
|
+
order_id=order_id,
|
|
102
|
+
amount=100
|
|
103
|
+
))
|
|
104
|
+
|
|
105
|
+
# 等待处理完成
|
|
106
|
+
wait_for_eventual_consistency(...)
|
|
107
|
+
|
|
108
|
+
# 验证:只创建了 1 个订单
|
|
109
|
+
assert order_count(order_id) == 1
|
|
110
|
+
# 验证:金额正确(不是 300)
|
|
111
|
+
assert get_order(order_id).amount == 100
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 3.2 幂等性检查清单
|
|
115
|
+
|
|
116
|
+
- [ ] 每条消息有唯一 `message_id` / `idempotency_key`
|
|
117
|
+
- [ ] 测试覆盖"完全相同消息重复消费"
|
|
118
|
+
- [ ] 测试覆盖"部分处理后重试"(模拟处理中途失败)
|
|
119
|
+
- [ ] 验证幂等键存储(Redis/DB)的过期策略
|
|
120
|
+
- [ ] 验证并发重复消息的处理(两条相同消息同时到达)
|
|
121
|
+
|
|
122
|
+
### 3.3 幂等性实现检查
|
|
123
|
+
|
|
124
|
+
| 检查点 | 通过条件 |
|
|
125
|
+
|--------|----------|
|
|
126
|
+
| 幂等键生成 | 由客户端生成,不依赖服务端 |
|
|
127
|
+
| 幂等键存储 | 有持久化存储,有合理 TTL |
|
|
128
|
+
| 幂等检查时机 | 在业务处理**之前**检查 |
|
|
129
|
+
| 重复请求响应 | 返回与首次相同的结果(不是错误) |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 4) 消息顺序与乱序处理测试
|
|
134
|
+
|
|
135
|
+
### 4.1 乱序场景
|
|
136
|
+
|
|
137
|
+
| 场景 | 示例 | 处理策略 |
|
|
138
|
+
|------|------|----------|
|
|
139
|
+
| 事件乱序 | 先收到"订单发货",后收到"订单创建" | 缓冲 + 重排序 / 拒绝 + 重试 |
|
|
140
|
+
| 版本冲突 | 收到旧版本更新覆盖新版本 | 版本号检查(Last-Write-Wins 或 拒绝) |
|
|
141
|
+
| 因果乱序 | 子事件先于父事件到达 | 依赖追踪 + 延迟处理 |
|
|
142
|
+
|
|
143
|
+
### 4.2 测试模式
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
# 测试:乱序消息能正确处理
|
|
147
|
+
def test_out_of_order_events():
|
|
148
|
+
order_id = "order-001"
|
|
149
|
+
|
|
150
|
+
# 故意按错误顺序发送
|
|
151
|
+
send_message(OrderShippedEvent(order_id=order_id, version=2))
|
|
152
|
+
send_message(OrderCreatedEvent(order_id=order_id, version=1))
|
|
153
|
+
|
|
154
|
+
wait_for_eventual_consistency(...)
|
|
155
|
+
|
|
156
|
+
# 验证:最终状态正确
|
|
157
|
+
order = get_order(order_id)
|
|
158
|
+
assert order.status == "SHIPPED"
|
|
159
|
+
assert order.version == 2
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 4.3 乱序处理检查清单
|
|
163
|
+
|
|
164
|
+
- [ ] 定义消息是否需要保序(全局有序 / 分区有序 / 无序)
|
|
165
|
+
- [ ] 若需要保序:使用分区键保证同一实体的消息有序
|
|
166
|
+
- [ ] 若允许乱序:实现版本号/时间戳检查
|
|
167
|
+
- [ ] 测试覆盖"乱序到达"场景
|
|
168
|
+
- [ ] 测试覆盖"版本冲突"场景
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 5) 超时与重试测试
|
|
173
|
+
|
|
174
|
+
### 5.1 超时测试模式
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
# 测试:下游超时时的处理
|
|
178
|
+
def test_downstream_timeout():
|
|
179
|
+
with mock_timeout(payment_service, timeout_ms=100):
|
|
180
|
+
result = order_service.process_order(order_id)
|
|
181
|
+
|
|
182
|
+
# 验证:超时后降级行为
|
|
183
|
+
assert result.status == "PENDING_PAYMENT"
|
|
184
|
+
assert result.retry_scheduled == True
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 5.2 重试测试模式
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
# 测试:重试逻辑正确
|
|
191
|
+
def test_retry_with_exponential_backoff():
|
|
192
|
+
attempt_times = []
|
|
193
|
+
|
|
194
|
+
with mock_failure(payment_service, fail_count=2):
|
|
195
|
+
with capture_attempts(payment_service, attempt_times):
|
|
196
|
+
result = order_service.process_order(order_id)
|
|
197
|
+
|
|
198
|
+
# 验证:重试了 3 次(1 初始 + 2 重试)
|
|
199
|
+
assert len(attempt_times) == 3
|
|
200
|
+
# 验证:重试间隔符合指数退避
|
|
201
|
+
assert attempt_times[1] - attempt_times[0] >= 100 # 第一次重试
|
|
202
|
+
assert attempt_times[2] - attempt_times[1] >= 200 # 第二次重试
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 5.3 超时/重试检查清单
|
|
206
|
+
|
|
207
|
+
- [ ] 每个异步操作都有显式超时设置
|
|
208
|
+
- [ ] 重试有最大次数限制(防止无限重试)
|
|
209
|
+
- [ ] 重试使用指数退避(防止重试风暴)
|
|
210
|
+
- [ ] 测试覆盖"超时后降级"场景
|
|
211
|
+
- [ ] 测试覆盖"重试成功"场景
|
|
212
|
+
- [ ] 测试覆盖"重试耗尽"场景
|
|
213
|
+
- [ ] 验证重试时的幂等性(重试不产生重复副作用)
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## 6) 补偿事务测试(Saga Pattern)
|
|
218
|
+
|
|
219
|
+
### 6.1 补偿测试模式
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
# 测试:部分失败时正确补偿
|
|
223
|
+
def test_saga_compensation():
|
|
224
|
+
order_id = "order-001"
|
|
225
|
+
|
|
226
|
+
# 模拟:库存扣减成功,支付失败
|
|
227
|
+
with mock_success(inventory_service):
|
|
228
|
+
with mock_failure(payment_service):
|
|
229
|
+
result = order_service.create_order(order_id)
|
|
230
|
+
|
|
231
|
+
wait_for_eventual_consistency(...)
|
|
232
|
+
|
|
233
|
+
# 验证:订单状态为失败
|
|
234
|
+
assert get_order(order_id).status == "FAILED"
|
|
235
|
+
# 验证:库存已回滚
|
|
236
|
+
assert get_inventory_reserved(order_id) == 0
|
|
237
|
+
# 验证:补偿记录存在
|
|
238
|
+
assert compensation_log_exists(order_id, "INVENTORY_ROLLBACK")
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### 6.2 补偿测试检查清单
|
|
242
|
+
|
|
243
|
+
- [ ] 每个可补偿操作都有对应的补偿操作
|
|
244
|
+
- [ ] 补偿操作本身是幂等的
|
|
245
|
+
- [ ] 测试覆盖"链路中间失败"的每个节点
|
|
246
|
+
- [ ] 测试覆盖"补偿操作失败"场景
|
|
247
|
+
- [ ] 验证补偿操作的执行顺序(逆序执行)
|
|
248
|
+
- [ ] 验证补偿日志/审计记录
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 7) 测试替身(Test Doubles)设计
|
|
253
|
+
|
|
254
|
+
### 7.1 消息队列测试替身
|
|
255
|
+
|
|
256
|
+
| 替身类型 | 用途 | 实现建议 |
|
|
257
|
+
|----------|------|----------|
|
|
258
|
+
| In-Memory Queue | 单元/集成测试 | 内存队列,同步处理 |
|
|
259
|
+
| Controllable Queue | 故障注入 | 可控制延迟、丢失、重复 |
|
|
260
|
+
| Record & Replay | 回归测试 | 记录生产消息,离线回放 |
|
|
261
|
+
|
|
262
|
+
### 7.2 测试替身检查清单
|
|
263
|
+
|
|
264
|
+
- [ ] 测试替身与真实实现有相同的接口
|
|
265
|
+
- [ ] 可以控制消息延迟
|
|
266
|
+
- [ ] 可以控制消息丢失
|
|
267
|
+
- [ ] 可以控制消息重复
|
|
268
|
+
- [ ] 可以控制消息乱序
|
|
269
|
+
- [ ] 可以注入处理失败
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## 8) verification.md 补充模板
|
|
274
|
+
|
|
275
|
+
在 `verification.md` 的测试计划中,若涉及异步系统,增加以下检查:
|
|
276
|
+
|
|
277
|
+
```markdown
|
|
278
|
+
### 异步系统测试检查(如适用)
|
|
279
|
+
|
|
280
|
+
#### 最终一致性
|
|
281
|
+
- [ ] 定义一致性窗口:< X 秒
|
|
282
|
+
- [ ] 测试覆盖"状态收敛成功"
|
|
283
|
+
- [ ] 测试覆盖"状态收敛超时"
|
|
284
|
+
|
|
285
|
+
#### 幂等性
|
|
286
|
+
- [ ] 消息包含 `idempotency_key`
|
|
287
|
+
- [ ] 测试覆盖"重复消息只处理一次"
|
|
288
|
+
- [ ] 测试覆盖"并发重复消息"
|
|
289
|
+
|
|
290
|
+
#### 消息顺序
|
|
291
|
+
- [ ] 声明保序要求:全局有序 / 分区有序 / 无序
|
|
292
|
+
- [ ] 测试覆盖"乱序消息处理"
|
|
293
|
+
|
|
294
|
+
#### 超时与重试
|
|
295
|
+
- [ ] 声明超时时间:X ms
|
|
296
|
+
- [ ] 声明重试策略:最多 N 次,指数退避
|
|
297
|
+
- [ ] 测试覆盖"超时降级"
|
|
298
|
+
- [ ] 测试覆盖"重试成功/耗尽"
|
|
299
|
+
|
|
300
|
+
#### 补偿事务(如适用)
|
|
301
|
+
- [ ] 定义补偿操作
|
|
302
|
+
- [ ] 测试覆盖"部分失败时补偿"
|
|
303
|
+
- [ ] 验证补偿操作幂等性
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## 9) 常见 Flaky Test 模式与修复
|
|
309
|
+
|
|
310
|
+
| Flaky 模式 | 原因 | 修复方法 |
|
|
311
|
+
|------------|------|----------|
|
|
312
|
+
| 固定 sleep | 时间不够或过长 | 改用轮询等待 + 超时 |
|
|
313
|
+
| 依赖消息顺序 | 并行消费导致乱序 | 使用幂等设计或显式排序 |
|
|
314
|
+
| 共享测试状态 | 测试间互相影响 | 每个测试使用独立数据 |
|
|
315
|
+
| 时间敏感断言 | 依赖系统时钟 | 注入可控时钟 |
|
|
316
|
+
| 资源竞争 | 端口/文件冲突 | 使用动态分配或隔离环境 |
|