名称: 测试驱动开发 描述: 统一的TDD技能,具有三种输入模式——从规范、任务或描述。使用仓库模式强制测试先行开发,包括proptest指导和反向压力集成。 类型: anthropic-skill 版本: “1.0”
测试驱动开发
概述
一个技能处理所有TDD工作流。使用现有仓库模式强制测试先行开发。三种输入模式处理不同的入口点——规范、任务文件或临时描述——但核心循环始终是RED → GREEN → REFACTOR。
输入模式
检测输入类型并遵循相应的模式:
模式 A: 从规范 (.spec.md)
当输入引用包含Given/When/Then验收标准的.spec.md文件时使用。
- 定位和解析 规范文件——提取所有Given/When/Then三元组
- 为每个标准生成一个测试存根,使用
todo!()主体:/// 规范: <spec-file> — 标准 #<N> /// 给定 <given text> /// 当 <when text> /// 然后 <then text> #[test] fn <spec_name>_标准_<N>_<slug>() { todo!("实现: <then text>"); } - 验证存根编译但失败:
cargo test --no-run -p <crate> - 继续到 TDD循环 以使存根通过
程序化支持: ralph_core::preflight::{extract_acceptance_criteria, extract_criteria_from_file, extract_all_criteria} 可以从规范文件中解析标准。
模式 B: 从任务 (.code-task.md)
当输入引用.code-task.md文件或特定实现任务时使用。
模式 C: 从描述
用于没有规范或任务文件的临时任务。
模式发现
在编写测试之前,发现现有约定:
rg --files -g "crates/*/tests/*.rs"
rg -n "#\[cfg\(test\)\]" crates/
阅读目标代码附近的2-3个相关测试文件。镜像:
- 测试模块布局、命名和断言风格
- 固定帮助器和测试实用程序
- 使用
tempfile、场景或harnesses
TDD循环
1) RED — 失败测试
- 为所需的确切行为编写测试
- 运行测试以确认失败出于正确原因
- 如果测试在没有实现的情况下通过,则测试是错误的
2) GREEN — 最小实现
- 编写最小代码以使测试通过
- 在此步骤中不添加额外功能或重构
3) REFACTOR — 清理
- 改进实现和测试,同时保持测试通过
- 与周围代码库约定对齐
- 每次更改后重新运行测试
Proptest指导
仅当以下所有条件满足时使用proptest:
- 函数是纯的(无I/O、无时间、无全局变量)
- 给定输入有确定性输出
- 非平凡输入空间或边缘情况
proptest! {
#[test]
fn round_trip(input in "[a-z0-9]{0,32}") {
let encoded = encode(input.as_str());
let decoded = decode(&encoded).expect("应该解码");
prop_assert_eq!(decoded, input);
}
}
如果没有强烈理由,不要引入proptest作为新依赖。
反向压力集成
在完成事件中包含覆盖率证据:
ralph emit "build.done" "tests: pass, lint: pass, typecheck: pass, audit: pass, coverage: pass (82%)"
当可行时运行cargo tarpaulin --out Html --output-dir coverage --skip-clean。如果无法运行覆盖率,说明原因并包括针对性测试证据。
测试位置规则
- 规范映射到单个模块 → 内联
#[cfg(test)]测试 - 规范跨越多个模块 → 集成测试在
crates/<crate>/tests/ - CLI行为 →
crates/ralph-cli/tests/ - 遵循目标crate中的现有模式
反模式
- 在测试之前编写实现
- 生成在没有实现的情况下通过的测试
- 从其他crate复制测试而不适应本地模式
- 当简单示例测试足够时添加proptest
- 发出没有覆盖率证据的完成事件