rtk-tdd

>

INSTALLATION
npx skills add https://github.com/rtk-ai/rtk --skill rtk-tdd
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Rust TDD Workflow

Three Laws of TDD

  • Do NOT write production code without a failing test
  • Write only enough test to fail (including compilation failure)
  • Write only enough production code to pass the failing test

Cycle: RED (test fails) -> GREEN (minimum to pass) -> REFACTOR (cleanup, cargo test)

Red-Green-Refactor Steps

1. Write test in #[cfg(test)] mod tests of the SAME file

2. cargo test MODULE::tests::test_name  -- must FAIL (red)

3. Implement the minimum in the function

4. cargo test MODULE::tests::test_name  -- must PASS (green)

5. Refactor if needed, re-run cargo test (still green)

6. cargo fmt && cargo clippy --all-targets && cargo test  (final gate)

Never skip step 2. If the test passes immediately, it tests nothing.

Idiomatic Rust Test Patterns

Pattern

Usage

When

Arrange-Act-Assert

Base structure for every test

Always

assert_eq! / assert!

Direct comparison / booleans

Deterministic values

assert!(result.is_err())

Error path testing

Invalid inputs

Result<()> return type

Tests with ? operator

Fallible functions

#[should_panic]

Expected panic

Invariants, preconditions

tempfile::NamedTempFile

File/I/O tests

Filesystem-dependent code

Patterns by Code Type

Code Type

Test Pattern

Example

Pure function (str -> str)

Input literal -> assert output

assert_eq!(truncate("hello", 3), "...")

Parsing/filtering

Raw string -> filter -> contains/not-contains

assert!(filter(raw).contains("expected"))

Validation/security

Boundary inputs -> assert bool

assert!(!is_valid("../etc/passwd"))

Error handling

Bad input -> is_err()

assert!(parse("garbage").is_err())

Struct/enum roundtrip

Construct -> serialize -> deserialize -> eq

assert_eq!(from_str(to_str(x)), x)

Naming Convention

test_{function}_{scenario}

test_{function}_{input_type}

Examples: test_truncate_edge_case, test_parse_invalid_input, test_filter_empty_string

When NOT to Use Pure TDD

  • Functions calling Command::new() -> test the parser, not the execution
  • std::process::exit() -> refactor to Result first, then test the Result
  • Direct I/O (SQLite, network) -> use tempfile/mock or test the pure logic separately
  • Main/CLI wiring -> covered by integration/smoke tests

Pre-Commit Gate

cargo fmt --all --check

cargo clippy --all-targets

cargo test

All 3 must pass. No exceptions. No #[allow(...)] without documented justification.

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card