Rust testing patterns and best practices. Use this skill when writing, reviewing, or modifying Rust tests. Covers test organization, assertions with pretty_assertions, parameterized tests, and testing multiple input formats.
Project-specific testing patterns for consistent, readable tests.
#[cfg(test)] modules (not separate tests/ directories)Import with prefixes to avoid shadowing (see hurry/tests/it/passthrough.rs:7 or hurry/src/cargo/build_args.rs:650):
use pretty_assertions::assert_eq as pretty_assert_eq;
Always construct the ENTIRE expected value upfront and compare in ONE operation:
// ✅ Prefer: Declare expected value first, single assertion
let expected = serde_json::json!({
"written": [key1, key2, key3],
"skipped": [],
"errors": [],
});
let body = response.json::<Value>();
pretty_assert_eq!(body, expected);
// ❌ Avoid: Property-by-property assertions
let body = response.json::<Value>();
pretty_assert_eq!(body["written"].len(), 3);
pretty_assert_eq!(body["skipped"], serde_json::json!([]));
assert!(body["written"].contains(&key1));
For unpredictable values (like error messages), keep property checks minimal:
// ✅ Good: Check structure separately
pretty_assert_eq!(body["written"], serde_json::json!([]));
pretty_assert_eq!(body["errors"].as_array().unwrap().len(), 1);
assert!(body["errors"][0]["error"].as_str().unwrap().contains("expected substring"));
See references/assertion-patterns.md for more examples
Use simple_test_case for tests with multiple variations (see hurry/tests/it/passthrough.rs:55-65 or hurry/src/cargo/build_args.rs:655-662):
use simple_test_case::test_case;
#[test_case("--release"; "long")]
#[test_case("-r"; "short")]
#[test]
fn parses_release_flag(flag: &str) {
let args = CargoBuildArguments::from_iter(vec![flag]);
assert!(args.is_release());
pretty_assert_eq!(args.profile(), Some("release"));
}
Each case runs independently: parses_release_flag::long, parses_release_flag::short
See references/parameterized-tests.md for testing multiple input formats
Use cargo nextest:
cargo nextest run -p {PACKAGE_NAME}
Available packages: hurry, courier, clients, e2e
Invoke when:
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer