两个面向 AI 编码代理的技能,用于为分布式和有状态系统设计并运行由断言驱动的测试。 二者共同产出一份结构化的 Markdown 测试计划,以及一份包含 10 种状态判定和明确的 SUT / 测试框架 / 检查器 / 环境归责分类的发现报告。审查者阅读这两份产物即可决定是否发布;无需重新运行任何其他内容。
适用于 Claude Code、Codex、Copilot CLI、Cursor、Gemini,或任何能读取 Markdown 并运行 shell 的代理。这些技能就是普通的 SKILL.md 文件。由代理执行它们;计划和发现报告即为输出。
一个技能负责设计计划,另一个负责运行计划。计划从产品的断言出发,生成与这些断言绑定的假设,并编写以每个场景试图证伪的断言命名的场景。对于一致性关键场景,每个场景还会将一个抽象模型(register | queue | log | lock | lease | ledger | …)绑定到操作历史模式、一个具名检查器,以及一个带有可观测落地证据的干扰源(nemesis)。计划以覆盖充分性论证和保守的置信度声明收尾。
测试分布式和有状态系统的默认做法——写几个集成测试就算完事——只能发现实际在生产环境中破坏这些系统的一小部分缺陷:部分网络分区、非确定性并发、崩溃恢复、升级/回滚、重放下的幂等性、时序敏感的排序。
这些技能强制执行一套有明确主张的工作流,汲取了该领域来之不易的经验:
端到端来看,这两个技能产出:
docs/testing-plans/<slug>.md ← plan with §0–§9 (see below)
test-sessions/<slug>/<UTC>/
├── session-log.md ← timeline + toolbox + env probe
├── logs/ ← per-scenario stdout/stderr
├── metrics/ ← metric snapshots
├── artifacts/ ← ephemeral harnesses, dumps
└── findings/
├── <scenario>.md ← per-scenario verdict (written as run proceeds)
└── report.md ← summary + adequacy + confidence delta
计划结构(审查者可以阅读此内容,并决定是否无需重新运行测试即可发布):
0. Architectural summary — system as it actually exists
1. Scope
1b. Claims under test — the spine
1c. Missing claims discovered — docs ↔ code drift
2. SUT model
3. Existing test inventory — what's already covered
4. Failure-mode hypotheses — tied to claim IDs
5. Coverage matrix — claim × hypothesis
6. Technique selection — from the catalog
6b. Environment requirements
7. Scenarios — each named after the claim, with
Target test file + Skeleton
7.M Model / history / — mandatory when the scenario falsifies
checker discipline a claim in {safety, durability,
idempotency, isolation, ordering,
membership}: model under test,
operation-history schema, named
checker, nemesis + landing evidence,
ambiguous-outcome handling, reduction
plan (SUT/harness/checker/env blame)
7b. Coverage adequacy argument — why these tests are enough
7c. Residual uncertainty — what stays unverified, and why ok
7d. Confidence statement — the reviewer's verdict
8. What this plan does NOT cover
9. Open questions / followups
### Scenario S3: linearizable_append_under_partition
- Falsifies if it FAILs: C1 (every acknowledged append is durable
and linearisable), C5 (leader election completes within 5s)
- Workload: 8 clients, 70% append / 30% read, 5min, key-skew zipf
- Faults: asymmetric partition isolating current leader at T+60s
for 30s
- Oracle: linearizability via Porcupine over per-key histories
§7.M (model / history / checker discipline)
- Model under test: log
- Operation history: default 11-field schema (op id, process id,
invoke/complete ts, op type, key, input,
output, error, timeout marker, node seen,
fault epoch). Recorded in-process + server-
side audit.
- Checker: linearizability (Porcupine) per-key, then
no-lost-ack against final state
- Nemesis + landing: asymmetric-partition (iptables drop one
direction). Landing evidence = iptables drop
counter goes 0 → 14,712 over the 30s window
AND raft log emits "leader-lost; starting
election" within 2s of injection.
- Ambiguous outcomes: timeouts → timeout_marker=true, complete_ts
=null, treated as could-have-succeeded;
retries are separate ops sharing input
- Reduction plan: if FAIL, bisect fault window + fix seed, then
classify SUT / harness / checker / environment
per references/test-case-reduction.md
| ID | 判定结果 | Nemesis 落地证据 | 缩减类别 |
|---|---|---|---|
| S3 | PASS-hardening | iptables 计数器 0→14,712;raft 在 T+1.8s 重新选举 | 不适用 |
| S4 | FAIL-reproducible | 分区已落地;Elle:键 K17 上出现 G2-item 异常 | SUT |
| S7 | INCONCLUSIVE-fault-not-proven | iptables 规则已安装但计数器保持为 0 —— 链错误 | harness |
| S9 | PARTIAL-model | 落地正常;检查器覆盖了单键,未覆盖跨键 | 不适用 |
(完整的 findings 模板包含 Oracle、Oracle 执行证据、
产物链接、adequacy-vs-plan 部分以及置信度差值 ——
参见 skills/executing-distributed-system-tests/assets/findings-report-template.md。)
将以下内容粘贴到任意 AI 编码 agent(Claude Code、Codex、Copilot CLI、 Cursor、Gemini,或任何其他能读取 Markdown 并运行 shell 的工具):
Read https://raw.githubusercontent.com/shenli/distributed-system-testing/main/INSTALL.md
and follow the instructions to install and configure
distributed-testing-skills for this agent.
智能体会获取 INSTALL.md,将仓库克隆到
~/.local/share/distributed-testing-skills/,并接入这些技能
(对于 Claude Code,在 ~/.claude/skills/ 下创建符号链接;对于其他智能体,
在 ~/AGENTS.md 中添加一个指针块)。
之后,让机器上的任意智能体“为这个系统设计一个测试计划”或“在 X 处执行该计划”, 它就会遵循 SKILL.md 工作流。
再次粘贴同一个单行命令。 INSTALL.md 是幂等的:
如果安装路径已存在,它会执行 git pull --ff-only;如果不存在,
它会执行 git clone。符号链接始终指向克隆的内容,
因此会自动获取新版本。~/AGENTS.md 中的指针块使用 HTML 标记,
每次运行都会被干净地替换——不会重复。
如果你对克隆的技能有本地修改,git pull --ff-only
会失败;智能体会停下来并在丢弃这些修改前询问你。
git clone https://github.com/shenli/distributed-system-testing.git \
~/.local/share/distributed-testing-skills
# Claude Code: symlink under ~/.claude/skills/
mkdir -p ~/.claude/skills
ln -snf ~/.local/share/distributed-testing-skills/skills/designing-distributed-system-tests \
~/.claude/skills/designing-distributed-system-tests
ln -snf ~/.local/share/distributed-testing-skills/skills/executing-distributed-system-tests \
~/.claude/skills/executing-distributed-system-tests
# Codex / Copilot CLI / Cursor / Gemini / others: see INSTALL.md
该仓库在
.claude-plugin/ 下带有插件清单和市场清单,因此 Claude Code 可以将其作为插件安装,
而无需创建符号链接:
/plugin marketplace add shenli/distributed-system-testing
/plugin install distributed-testing-skills@distributed-testing-skills
这两个技能都会从 skills/ 目录自动发现。上文所述的一行式 INSTALL.md 流程仍然是 agent 无关的路径(Codex、Copilot CLI、Cursor、Gemini)。
技能安装完成后,有两种方式驱动它们:
随意提问(Claude Code 自动触发):
Design a project-wide test plan for this codebase.
Execute the plan at ./testing-plans/<slug>.md against this codebase.
技能描述采用自然措辞,例如“设计测试计划”、“执行计划”、“运行稳定性测试”、“设计发布验证计划”等。
对于特定模式、输出路径或非自动触发的 agent,USAGE.md 为每个工作流(分别在各自模式下进行设计与执行)提供了可复制粘贴的提示词,以及关于范围、环境探测和长时间运行检查点的提示。
designing-distributed-system-tests