en un clic
rust-testing
// When and what to test in Rust. Types handle compile-time invariants; tests verify runtime behavior types cannot express.
// When and what to test in Rust. Types handle compile-time invariants; tests verify runtime behavior types cannot express.
Use when designing error types, wrapping third-party errors, seeing repeated map_err calls with same error types, building modular error hierarchies with thiserror, choosing between custom errors vs anyhow::Result, or writing Result-returning functions in Rust.
Search and evaluate Rust crates for a problem. Presents options for user approval.
Use when writing Rust structs with generic type parameters, implementing traits for polymorphism, designing service/client/handler layers, choosing between Box<dyn Trait> vs enum vs generics, adding middleware (retry, logging, caching), wrapping or decorating existing types, forwarding methods to inner fields, or refactoring to reduce duplication across similar structs.
Review Rust code for correctness, design principles, and rule compliance.
Helper skill for searching Rust documentation. Use when agents need to find crate docs, API usage, trait implementations, or examples from local and online sources.
| name | rust-testing |
| description | When and what to test in Rust. Types handle compile-time invariants; tests verify runtime behavior types cannot express. |
Core principle: Test what types cannot prove.
Types already guarantee these - no tests needed:
| Guarantee | Type Mechanism |
|---|---|
| Can't mix UserId/OrderId | Newtype |
| Invalid state transitions | State machine (PhantomData) |
| Missing required fields | Type-state builder |
| Null/missing values | Option |
// ❌ Pointless test - compiler already rejects wrong types
#[test]
fn user_id_not_mixable_with_order_id() { }
// ❌ Pointless - method doesn't exist on Draft
#[test]
fn draft_order_cannot_pay() { }
Test runtime behavior types cannot express:
| Test | Reason |
|---|---|
| Validation logic | Regex, range checks, business rules |
| Algorithm correctness | Math, sorting, transformation |
| State transition conditions | "Can submit only if items > 0" |
| External interactions | DB, network, filesystem |
| Error paths | Specific error variants returned |
Types say "Email is valid", tests prove the validation is correct.
#[test]
fn email_rejects_missing_at() {
assert!(Email::new("invalid").is_err());
}
#[test]
fn email_rejects_empty() {
assert!(Email::new("").is_err());
}
Types enforce which transitions exist; tests verify when they succeed.
#[test]
fn cannot_submit_empty_order() {
let order = Order::<Draft>::new();
assert!(order.submit().is_err()); // Business rule, not type rule
}
#[test]
fn order_total_sums_items() {
let mut order = Order::new();
order.add(Item::new(100));
order.add(Item::new(50));
assert_eq!(order.total(), 150);
}
#[test]
fn returns_not_found_for_missing_user() {
let result = repo.get_user(UserId::new(999));
assert!(matches!(result, Err(RepoError::NotFound { .. })));
}
Use for public API examples that also verify correctness.
/// ```
/// let email = Email::new("user@example.com")?;
/// # Ok::<(), EmailError>(())
/// ```
///
/// ```compile_fail
/// // Proves type safety - won't compile
/// get_order(order_id, user_id); // Wrong argument order
/// ```
compile_fail documents type guarantees without runtime tests.
Use tests/ for cross-module behavior and external dependencies.
tests/
├── api_integration.rs # Full workflows
└── common/mod.rs # Shared fixtures
Debug, Clone)From/Into implementationscompile_fail doc tests document type safetyrust-type-driven-development - types that eliminate testsrust-error-handling - testing error variants