Configures and runs Rust's built-in `cargo test` - `#[test]` + `#[should_panic]` + `Result<(), E>` returns; integration tests in `tests/`; doc-tests embedded in `///` comments; `--lib` / `--bins` / `--all-targets` / `--workspace` selection; `cargo bench` (nightly) + Criterion (stable); `cargo test -- --test-threads=1` for serial; `cargo test -- --nocapture` to see println output. Use for any Rust project - testing is built into Cargo, no install needed.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Per doc.rust-lang.org/book/ch11-00-testing.html:
Rust's testing is built into Cargo. The #[test] attribute marks
test functions; cargo test discovers and runs them.
Three test categories per the Rust Book:
| Category | Location | Purpose |
|---|---|---|
| Unit tests | Same file as code, in #[cfg(test)] mod tests { ... } | Test private + internal logic |
| Integration tests | tests/ directory at crate root | Test public API as external user |
| Doc tests | Inside /// doc comments | Verify documentation examples |
#[cfg(test)] mod tests { ... } block next to the code; put cross-crate scenarios in tests/ (Steps 1, 5).assert_eq! / assert_ne! / assert!; return Result<(), E> and use ? instead of unwrap() (Steps 2, 4).#[should_panic(expected = "...")], and mark slow/networked tests #[ignore = "reason"] (Steps 3, 8).cargo test --all-targets --workspace locally; filter by name pattern and add -- --nocapture to see println! output (Steps 1, 7)./// comments, verified by cargo test --doc (Step 6).cargo llvm-cov and Criterion (see references/coverage-and-benchmarks.md).// src/math.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adds_two_numbers() {
assert_eq!(add(1, 2), 3);
}
#[test]
fn handles_zero() {
assert_eq!(add(0, 0), 0);
}
}Run:
cargo test # all tests
cargo test add # filter by name pattern
cargo test --lib # only unit tests in lib
cargo test --bins # binary tests
cargo test --all-targets # everything
cargo test --workspace # multi-crate workspaceassert!(condition);
assert!(condition, "format message: {}", value);
assert_eq!(actual, expected);
assert_eq!(actual, expected, "with message");
assert_ne!(actual, unexpected);
// Custom error message:
assert!(actual > 0, "Expected positive, got {}", actual);For richer assertions, the pretty_assertions crate provides
diff-rich macros:
use pretty_assertions::assert_eq;
assert_eq!(actual_complex_struct, expected_complex_struct);
// shows colorized diff on failure#[should_panic]#[test]
#[should_panic]
fn panics_on_negative() {
sqrt(-1.0);
}
#[test]
#[should_panic(expected = "negative")]
fn specific_panic_message() {
sqrt(-1.0);
// panics with message containing "negative"
}Result return for ?-style propagation#[test]
fn parses_config() -> Result<(), Box<dyn Error>> {
let cfg = Config::from_file("test/fixtures/config.toml")?;
assert_eq!(cfg.port, 8080);
Ok(())
}Test passes if Ok(()); fails if Err(...). Avoids unwrap()
boilerplate; allows ? operator in test bodies.
my-crate/
src/
lib.rs
tests/
integration_test.rs # automatically discovered
common/
mod.rs # shared helpers (note: NO mod.rs in tests/ root)// tests/integration_test.rs
use my_crate::Calculator;
#[test]
fn end_to_end() {
let c = Calculator::new();
assert_eq!(c.add(1, 2), 3);
}
mod common; // shared test helpers from tests/common/mod.rsEach file in tests/ compiles to its own binary - slower but
better-isolated than unit tests.
/// Adds two numbers.
///
/// # Examples
///
/// ```
/// use my_crate::math::add;
/// assert_eq!(add(1, 2), 3);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}cargo test --doc runs only doc tests; cargo test runs everything
including docs. The example IS the test - drift between docs +
implementation is caught.
# Examples heading is convention; required for cargo doc HTML
rendering to show the example.
cargo test -- --test-threads=1 # serial (single-threaded)
cargo test -- --nocapture # show stdout (println in tests)
cargo test -- --show-output # show stdout for passed tests too
cargo test -- --ignored # only run #[ignore]-marked tests
cargo test -- --include-ignored # run both ignored + normal
cargo test -- --list # list tests without running
cargo test some_pattern -- --exact # exact match (no substring)#[ignore] for slow tests#[test]
#[ignore = "Requires network access"]
fn integration_with_external_api() {
// ...
}Run via cargo test -- --include-ignored.
Both need an extra crate installed (cargo-llvm-cov / cargo-tarpaulin
for coverage; Criterion for benchmarks on stable). Full commands, the
Cargo.toml bench wiring, and the Criterion example are in
references/coverage-and-benchmarks.md.
- run: cargo test --all-targets --workspace
- run: cargo test --doc # explicit doc tests
- run: cargo install cargo-llvm-cov
- run: cargo llvm-cov --lcov --output-path coverage.lcov
- uses: codecov/codecov-action@v4
with: { files: coverage.lcov }A crate exposes add(a, b) in src/math.rs and you need it tested before
release.
#[cfg(test)] mod tests block with adds_two_numbers and handles_zero, each using assert_eq! (Step 1)./// comment on add so the documented example is executed (Step 6).cargo test --all-targets: the unit block prints test result: ok. 2 passed, then Doc-tests my_crate ... 1 passed.cargo llvm-cov --fail-under-lines 80; it reports add fully covered and exits 0 (see references/coverage-and-benchmarks.md).cargo test --all-targets --workspace plus the coverage gate on every push (Step 10).Result: unit, doc, and coverage checks are all green - the function is release-ready.
| Anti-pattern | Why it fails | Fix |
|---|---|---|
Skip --all-targets | Doc tests + bench + examples not run | Always --all-targets (Step 1) |
Use unwrap() in test bodies | Test failure message is "called unwrap on None"; useless | Use Result<(), E> return + ? (Step 4) |
#[ignore] without reason | Forgotten ignored tests | Always include = "reason" (Step 8) |
assert!(x == y) instead of assert_eq! | Loses diff in failure | Use assert_eq! (Step 2) |
| Skip Criterion for performance work | Stdlib #[bench] is nightly-only; CI breaks | Use Criterion on stable (see references/coverage-and-benchmarks.md) |
mod tests shared state.mockall is the community standard
for trait mocking.rstest (see
rstest-tests).cargo test referencego-test,
ginkgo-tests,
rstest-tests - sister toolsproptest-testing (qa-property-based) - Rust property-basedtest-code-conventions (qa-test-review)