Install
openclaw skills install imbeasting-test-driven-developmentUnified TDD skill with three input modes — from spec, from task, or from description. Enforces test-first development using repository patterns, with proptes...
openclaw skills install imbeasting-test-driven-developmentOne skill for all TDD workflows. Enforces test-first development using existing repository patterns. Three input modes handle different entry points — specs, task files, or ad-hoc descriptions — but the core cycle is always RED → GREEN → REFACTOR.
Detect the input type and follow the corresponding mode:
.spec.md)Use when the input references a .spec.md file with Given/When/Then acceptance criteria.
todo!() bodies:
/// Spec: <spec-file> — Criterion #<N>
/// Given <given text>
/// When <when text>
/// Then <then text>
#[test]
fn <spec_name>_criterion_<N>_<slug>() {
todo!("Implement: <then text>");
}
cargo test --no-run -p <crate>Programmatic support: ralph_core::preflight::{extract_acceptance_criteria, extract_criteria_from_file, extract_all_criteria} can parse criteria from spec files.
.code-task.md)Use when the input references a .code-task.md file or a specific implementation task.
Use for ad-hoc tasks without a spec or task file.
Before writing tests, discover existing conventions:
rg --files -g "crates/*/tests/*.rs"
rg -n "#\[cfg\(test\)\]" crates/
Read 2-3 relevant test files near the target code. Mirror:
tempfile, scenarios, or harnessesUse proptest only when ALL of:
proptest! {
#[test]
fn round_trip(input in "[a-z0-9]{0,32}") {
let encoded = encode(input.as_str());
let decoded = decode(&encoded).expect("should decode");
prop_assert_eq!(decoded, input);
}
}
Don't introduce proptest as a new dependency without strong justification.
Include coverage evidence in completion events:
ralph emit "build.done" "tests: pass, lint: pass, typecheck: pass, audit: pass, coverage: pass (82%)"
Run cargo tarpaulin --out Html --output-dir coverage --skip-clean when feasible. If coverage cannot be run, state why and include targeted test evidence instead.
#[cfg(test)] testscrates/<crate>/tests/crates/ralph-cli/tests/