Tests rust
/rust-testCrée, exécute et améliore les tests Rust pour sécuriser les changements.
description: Enforce TDD workflow for Rust. Write tests first, then implement. Verify 80%+ coverage with cargo-llvm-cov.
Rust TDD Command
This command enforces test-driven development methodology for Rust code using #[test], rstest, proptest, and mockall.
What This Command Does
- Define Types/Traits: Scaffold function signatures with
todo!() - Write Tests: Create comprehensive test module (RED)
- Run Tests: Verify tests fail for the right reason
- Implement Code: Write minimal code to pass (GREEN)
- Refactor: Improve while keeping tests green
- Check Coverage: Ensure 80%+ coverage with cargo-llvm-cov
When to Use
Use /rust-test when:
- Implementing new Rust functions, methods, or traits
- Adding test coverage to existing Rust code
- Fixing bugs (write failing test first)
- Building critical business logic
- Learning TDD workflow in Rust
TDD Cycle
RED -> Write failing test first
GREEN -> Implement minimal code to pass
REFACTOR -> Improve code, tests stay green
REPEAT -> Next test caseExample Session
User: /rust-test I need a function to validate user registration
Agent:
# TDD Session: Registration Validator
## Step 1: Define Interface
// src/validator.rs
pub struct RegistrationRequest {
pub name: String,
pub email: String,
pub password: String,
}
pub enum ValidationResult {
Valid,
Invalid(Vec<String>),
}
pub fn validate_registration(request: &RegistrationRequest) -> ValidationResult {
todo!()
}
## Step 2: Write Tests (RED)
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn validregistrationreturns_valid() {
let request = RegistrationRequest {
name: "Alice".into(),
email: "alice@example.com".into(),
password: "SecureP@ss1".into(),
};
assert!(matches!(validate_registration(&request), ValidationResult::Valid));
}
#[test]
fn blanknamereturns_invalid() {
let request = RegistrationRequest {
name: "".into(),
email: "alice@example.com".into(),
password: "SecureP@ss1".into(),
};
match validate_registration(&request) {
ValidationResult::Invalid(errors) => {
assert!(errors.contains(&"Name is required".to_string()));
}
ValidationResult::Valid => panic!("expected Invalid"),
}
}
#[test]
fn invalidemailreturns_invalid() {
let request = RegistrationRequest {
name: "Alice".into(),
email: "not-an-email".into(),
password: "SecureP@ss1".into(),
};
assert!(matches!(
validate_registration(&request),
ValidationResult::Invalid(_)
));
}
#[test]
fn shortpasswordreturns_invalid() {
let request = RegistrationRequest {
name: "Alice".into(),
email: "alice@example.com".into(),
password: "short".into(),
};
assert!(matches!(
validate_registration(&request),
ValidationResult::Invalid(_)
));
}
}
## Step 3: Run Tests — Verify FAIL
$ cargo test
running 4 tests
test tests::validregistrationreturns_valid ... FAILED (not yet implemented)
test tests::blanknamereturns_invalid ... FAILED
test tests::invalidemailreturns_invalid ... FAILED
test tests::shortpasswordreturns_invalid ... FAILED
Tests fail as expected (todo! panic).
## Step 4: Implement Minimal Code (GREEN)
pub fn validate_registration(request: &RegistrationRequest) -> ValidationResult {
let mut errors = Vec::new();
if request.name.trim().is_empty() {
errors.push("Name is required".into());
}
if !request.email.contains('@') {
errors.push("Invalid email format".into());
}
if request.password.len() < 8 {
errors.push("Password must be at least 8 characters".into());
}
if errors.is_empty() {
ValidationResult::Valid
} else {
ValidationResult::Invalid(errors)
}
}
## Step 5: Run Tests — Verify PASS
$ cargo test
running 4 tests
test tests::validregistrationreturns_valid ... ok
test tests::blanknamereturns_invalid ... ok
test tests::invalidemailreturns_invalid ... ok
test tests::shortpasswordreturns_invalid ... ok
test result: ok. 4 passed; 0 failed
All tests passing!
## Step 6: Check Coverage
$ cargo llvm-cov
Coverage: 100.0% of lines
Coverage: 100%
## TDD Complete!Test Patterns
Unit Tests
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adds_two_numbers() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn handles_error() -> Result<(), Box<dyn std::error::Error>> {
let result = parse_config(r#"port = 8080"#)?;
assert_eq!(result.port, 8080);
Ok(())
}
}Parameterized Tests with rstest
use