Agent Skill
2/7/2026test
Use this skill when writing or running tests. Enforces rstest for parametrized tests and DRY test patterns. Use when creating new tests, fixing test failures, or improving test coverage.
F
fohte
0GitHub Stars
1Views
npx skills add fohte/armyknife
SKILL.md
| Name | test |
| Description | Use this skill when writing or running tests. Enforces rstest for parametrized tests and DRY test patterns. Use when creating new tests, fixing test failures, or improving test coverage. |
name: test description: Use this skill when writing or running tests. Enforces rstest for parametrized tests and DRY test patterns. Use when creating new tests, fixing test failures, or improving test coverage. allowed-tools: Read, Grep, Glob, Edit, Write, Bash(cargo test:*)
Testing with rstest
This project uses rstest for DRY, parametrized tests.
Running Tests
cargo test # Run all tests
cargo test <test_name> # Run specific test
cargo test -- --nocapture # Show stdout
Coverage
Use cargo-llvm-cov to measure test coverage locally:
cargo llvm-cov # Run tests with coverage (text summary)
cargo llvm-cov --html # Generate HTML report in target/llvm-cov/html/
cargo llvm-cov --lcov --output-path lcov.info # Generate LCOV format (used in CI)
Coverage is automatically measured and uploaded to Codecov in CI.
Writing Tests
Always prefer rstest over plain #[test]
Use #[rstest] with #[case] for multiple inputs:
use rstest::*;
#[rstest]
#[case::empty("", true)]
#[case::whitespace(" ", true)]
#[case::valid("hello", false)]
fn test_is_blank(#[case] input: &str, #[case] expected: bool) {
assert_eq!(is_blank(input), expected);
}
Use fixtures for shared setup
#[fixture]
fn repository() -> InMemoryRepository {
let mut r = InMemoryRepository::default();
// setup
r
}
#[rstest]
fn test_find(repository: InMemoryRepository) {
// repository is automatically injected
}
Combine cases with values
#[rstest]
#[case::admin(User::Admin)]
#[case::guest(User::Guest)]
fn test_access(
#[case] user: User,
#[values("read", "write", "delete")] action: &str,
) {
// Generates 6 tests: admin+read, admin+write, ...
}
Use indoc for multiline test input
use indoc::indoc;
#[rstest]
#[case::with_frontmatter(
indoc! {r#"
---
title: "Test"
---
Body content
"#},
"Test",
"Body content\n"
)]
fn test_parse(#[case] input: &str, #[case] title: &str, #[case] body: &str) {
let doc = parse(input);
assert_eq!(doc.title, title);
assert_eq!(doc.body, body);
}
Test Naming
- Use
#[case::descriptive_name]for named cases - Test function:
test_<function>_<scenario>orshould_<behavior>
DRY Principles
- Extract common assertions into helper functions
- Use fixtures for repeated setup
- Parametrize similar tests with
#[case] - Use
#[values]for combinatorial testing
Skills Info
Original Name:testAuthor:fohte
Download