Rust testing
Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/rust-testing
When to activate: Rust tests, unit tests, integration tests, doc tests, benchmarks, proptest, test helpers, test organizationFrom its SKILL.md
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill rust-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.8 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Rust Testing Patterns
Unit Tests
Place unit tests in the same file as the code under test inside a #[cfg(test)] module.
pub fn add(a: i32, b: i32) -> i32 { a + b }
pub fn divide(a: f64, b: f64) -> Option<f64> {
if b == 0.0 { None } else { Some(a / b) }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_positive_numbers() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn divide_by_zero_returns_none() {
assert_eq!(divide(10.0, 0.0), None);
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn panics_on_bad_index() {
let v: Vec<i32> = vec![];
let _ = v[0];
}
}
Integration Tests
Live in the tests/ directory at the crate root; each file is a separate crate.
// tests/api_tests.rs
use my_crate::{App, Config};
fn setup_app() -> App {
App::new(Config { db_url: ":memory:".into(), port: 0 })
}
#[test]
fn creates_user_and_retrieves_it() {
let app = setup_app();
let id = app.create_user("[email protected]").unwrap();
let user = app.get_user(id).unwrap();
assert_eq!(user.email, "[email protected]");
}
// Shared test helpers go in tests/common/mod.rs
Doc Tests
Code examples in doc comments are compiled and run as tests.
/// Adds two numbers together.
///
/// # Examples
///
/// ```
/// use my_crate::add;
/// assert_eq!(add(2, 3), 5);
/// assert_eq!(add(-1, 1), 0);
/// ```
pub fn add(a: i32, b: i32) -> i32 { a + b }
Property-Based Testing with proptest
# Cargo.toml
[dev-dependencies]
proptest = "1"
use proptest::prelude::*;
fn sort_and_dedup(mut v: Vec<i32>) -> Vec<i32> {
v.sort();
v.dedup();
v
}
proptest! {
#[test]
fn sorted_output_is_actually_sorted(v in prop::collection::vec(any::<i32>(), 0..100)) {
let result = sort_and_dedup(v);
for window in result.windows(2) {
prop_assert!(window[0] <= window[1]);
}
}
#[test]
fn dedup_removes_consecutive_duplicates(v in prop::collection::vec(any::<i32>(), 0..100)) {
let result = sort_and_dedup(v);
for window in result.windows(2) {
prop_assert_ne!(window[0], window[1]);
}
}
}
Async Tests with tokio
[dev-dependencies]
tokio = { version = "1", features = ["full", "test-util"] }
#[tokio::test]
async fn fetches_data_successfully() {
let client = HttpClient::new();
let response = client.get("https://httpbin.org/json").await.unwrap();
assert_eq!(response.status(), 200);
}
// Control time in tests
#[tokio::test]
async fn timeout_fires_after_delay() {
tokio::time::pause();
let result = tokio::time::timeout(
std::time::Duration::from_secs(1),
async {
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
},
).await;
tokio::time::advance(std::time::Duration::from_secs(2)).await;
assert!(result.is_err());
}
Test Fixtures and Cleanup Guards
struct TestDb { path: std::path::PathBuf }
impl TestDb {
fn new() -> Self {
let path = std::env::temp_dir().join(format!("test_{}.db", rand_suffix()));
Self { path }
}
}
impl Drop for TestDb {
fn drop(&mut self) {
let _ = std::fs::remove_file(&self.path);
}
}
#[test]
fn database_stores_users() {
let db = TestDb::new();
// cleanup automatic on drop
}
Benchmarks with Criterion
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
[[bench]]
name = "my_benchmark"
harness = false
// benches/my_benchmark.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
fn bench_fibonacci(c: &mut Criterion) {
let mut group = c.benchmark_group("fibonacci");
for i in [10u64, 20, 30].iter() {
group.bench_with_input(BenchmarkId::from_parameter(i), i, |b, &i| {
b.iter(|| fibonacci(black_box(i)));
});
}
group.finish();
}
criterion_group!(benches, bench_fibonacci);
criterion_main!(benches);
Common Anti-Patterns
- Testing private implementation details — test through the public API
- Sharing mutable state across parallel tests — use
#[serial_test]crate or redesign - Using real network/filesystem without isolation — use
tempfilecrate or mock traits unwrap()in tests without context — preferexpect("why this should succeed")- Non-deterministic test order dependence — each test must be fully independent
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.