KS
Killer-Skills

rust-testing-verification — how to use rust-testing-verification how to use rust-testing-verification, rust-testing-verification setup guide, proptest vs Criterion, cargo-fuzz install, rust-testing-verification alternative, what is rust-testing-verification, rust-testing-verification tutorial, cargo-miri tutorial, property-based testing in Rust

v1.0.0
GitHub

About this Skill

Perfect for Rust Development Agents needing comprehensive testing and verification capabilities. rust-testing-verification is a set of production testing strategies for correctness and performance validation using proptest, Criterion, cargo-fuzz, and cargo-miri.

Features

Writing comprehensive test suites using proptest 1.x
Finding edge cases automatically with cargo-fuzz 0.11.x
Verifying trait implementations with cargo-miri Latest nightly
Benchmarking performance using Criterion 0.5.x
Detecting undefined behavior with property-based testing
Ensuring code correctness with basic property tests

# Core Topics

matthewharwood matthewharwood
[0]
[0]
Updated: 3/6/2026

Quality Score

Top 5%
54
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add matthewharwood/engmanager.xyz

Agent Capability Analysis

The rust-testing-verification MCP Server by matthewharwood is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use rust-testing-verification, rust-testing-verification setup guide, proptest vs Criterion.

Ideal Agent Persona

Perfect for Rust Development Agents needing comprehensive testing and verification capabilities.

Core Value

Empowers agents to write comprehensive test suites using proptest, Criterion, and cargo-fuzz, ensuring code correctness and performance validation through property-based testing and benchmarking.

Capabilities Granted for rust-testing-verification MCP Server

Automating edge case detection with proptest
Verifying trait implementations using cargo-miri
Benchmarking performance with Criterion

! Prerequisites & Limits

  • Requires Rust nightly for cargo-miri
  • Limited to Rust programming language
  • Version dependencies: proptest 1.x, Criterion 0.5.x, cargo-fuzz 0.11.x
Project
SKILL.md
13.3 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

Rust Testing & Verification

Production testing strategies for correctness and performance validation

Version Context

  • proptest: 1.x
  • Criterion: 0.5.x
  • cargo-fuzz: 0.11.x
  • cargo-miri: Latest nightly

When to Use This Skill

  • Writing comprehensive test suites
  • Finding edge cases automatically
  • Verifying trait implementations
  • Benchmarking performance
  • Detecting undefined behavior
  • Ensuring code correctness

Property-Based Testing

Basic Property Tests

rust
1use proptest::prelude::*; 2 3proptest! { 4 /// Property: Serialization round-trip preserves data 5 #[test] 6 fn user_serialization_roundtrip(user in any::<User>()) { 7 let serialized = serde_json::to_string(&user)?; 8 let deserialized: User = serde_json::from_str(&serialized)?; 9 prop_assert_eq!(user, deserialized); 10 } 11 12 /// Property: Email validation accepts valid emails 13 #[test] 14 fn email_validation_accepts_valid_emails( 15 email in r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" 16 ) { 17 let result = Email::parse(&email); 18 prop_assert!(result.is_ok()); 19 } 20 21 /// Property: Vec operations maintain size invariants 22 #[test] 23 fn vec_push_increases_len( 24 mut vec in prop::collection::vec(any::<i32>(), 0..100), 25 value in any::<i32>() 26 ) { 27 let original_len = vec.len(); 28 vec.push(value); 29 prop_assert_eq!(vec.len(), original_len + 1); 30 } 31}

Advanced Property Tests

rust
1proptest! { 2 /// Property: Account balance invariants 3 #[test] 4 fn account_balance_invariants( 5 initial_balance in 0u64..1_000_000, 6 transactions in prop::collection::vec( 7 prop::oneof![ 8 (1u64..10_000).prop_map(Transaction::Deposit), 9 (1u64..10_000).prop_map(Transaction::Withdrawal), 10 ], 11 1..100 12 ) 13 ) { 14 let mut account = Account::new(initial_balance); 15 let mut expected_balance = initial_balance; 16 17 for transaction in transactions { 18 match transaction { 19 Transaction::Deposit(amount) => { 20 account.deposit(amount)?; 21 expected_balance += amount; 22 } 23 Transaction::Withdrawal(amount) => { 24 if account.balance() >= amount { 25 account.withdraw(amount)?; 26 expected_balance -= amount; 27 } 28 } 29 } 30 31 // Invariant: balance must always be non-negative 32 prop_assert!(account.balance() >= 0); 33 prop_assert_eq!(account.balance(), expected_balance); 34 } 35 } 36 37 /// Property: Sorted vector stays sorted after insertion 38 #[test] 39 fn sorted_insert_maintains_order( 40 mut sorted_vec in prop::collection::vec(any::<i32>(), 0..100) 41 .prop_map(|mut v| { v.sort(); v }), 42 value in any::<i32>() 43 ) { 44 sorted_vec.insert( 45 sorted_vec.binary_search(&value).unwrap_or_else(|i| i), 46 value 47 ); 48 49 // Verify still sorted 50 for i in 1..sorted_vec.len() { 51 prop_assert!(sorted_vec[i - 1] <= sorted_vec[i]); 52 } 53 } 54}

Custom Generators

rust
1use proptest::strategy::{Strategy, BoxedStrategy}; 2 3/// Custom strategy for generating valid users 4fn arb_user() -> BoxedStrategy<User> { 5 ( 6 r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", 7 r"[A-Z][a-z]+ [A-Z][a-z]+", 8 13u8..=120u8, 9 ) 10 .prop_map(|(email, name, age)| { 11 User { 12 id: UserId::new(), 13 email, 14 name, 15 age, 16 created_at: chrono::Utc::now(), 17 } 18 }) 19 .boxed() 20} 21 22proptest! { 23 #[test] 24 fn test_with_valid_users(user in arb_user()) { 25 // Test only runs with valid user data 26 prop_assert!(user.age >= 13 && user.age <= 120); 27 prop_assert!(user.email.contains('@')); 28 } 29}

Fuzz Testing

Basic Fuzz Target

rust
1// fuzz/fuzz_targets/parse_input.rs 2#![no_main] 3use libfuzzer_sys::fuzz_target; 4 5fuzz_target!(|data: &[u8]| { 6 // Should never panic on arbitrary input 7 if let Ok(s) = std::str::from_utf8(data) { 8 let _ = parse_user_input(s); 9 } 10});

Structured Fuzzing

rust
1// fuzz/fuzz_targets/api_request.rs 2#![no_main] 3use libfuzzer_sys::fuzz_target; 4use arbitrary::Arbitrary; 5 6#[derive(Debug, Arbitrary)] 7struct FuzzApiRequest { 8 method: String, 9 path: String, 10 headers: Vec<(String, String)>, 11 body: Vec<u8>, 12} 13 14fuzz_target!(|req: FuzzApiRequest| { 15 // Test API handler doesn't panic on arbitrary inputs 16 let _ = handle_request( 17 req.method, 18 req.path, 19 req.headers, 20 req.body, 21 ); 22});

Regression Tests from Fuzzing

rust
1#[cfg(test)] 2mod fuzz_regression_tests { 3 use super::*; 4 5 /// Edge cases discovered by fuzzing 6 #[test] 7 fn test_known_edge_cases() { 8 let edge_cases = vec![ 9 "", // Empty input 10 "\0", // Null byte 11 "🦀", // Unicode 12 &"x".repeat(10_000), // Large input 13 "\n\r\t", // Whitespace 14 "{{{{", // Unbalanced braces 15 ]; 16 17 for case in edge_cases { 18 // Should handle gracefully without panicking 19 let result = parse_user_input(case); 20 assert!(result.is_ok() || result.is_err()); 21 } 22 } 23}

Benchmark Testing

Basic Criterion Benchmarks

rust
1use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId}; 2 3fn benchmark_user_operations(c: &mut Criterion) { 4 let mut group = c.benchmark_group("user_operations"); 5 6 // Benchmark with different input sizes 7 for size in [10, 100, 1000, 10000].iter() { 8 group.bench_with_input( 9 BenchmarkId::new("lookup", size), 10 size, 11 |b, &size| { 12 let users = generate_test_users(size); 13 b.iter(|| { 14 let id = &users[rand::random::<usize>() % users.len()].id; 15 black_box(lookup_user(black_box(id))) 16 }) 17 }, 18 ); 19 } 20 21 group.finish(); 22} 23 24criterion_group!(benches, benchmark_user_operations); 25criterion_main!(benches);

Advanced Benchmarking

rust
1use criterion::{Criterion, BenchmarkId, Throughput}; 2use std::time::Duration; 3 4fn benchmark_serialization(c: &mut Criterion) { 5 let mut group = c.benchmark_group("serialization"); 6 7 // Configure statistical parameters 8 group.sample_size(100); 9 group.measurement_time(Duration::from_secs(10)); 10 group.confidence_level(0.95); 11 12 for size in [10, 100, 1000].iter() { 13 let data = generate_data(*size); 14 15 // Set throughput for bytes per second calculation 16 group.throughput(Throughput::Bytes(data.len() as u64)); 17 18 group.bench_with_input( 19 BenchmarkId::new("json", size), 20 &data, 21 |b, data| { 22 b.iter(|| { 23 let serialized = serde_json::to_string(black_box(data)).unwrap(); 24 black_box(serialized) 25 }) 26 }, 27 ); 28 29 group.bench_with_input( 30 BenchmarkId::new("bincode", size), 31 &data, 32 |b, data| { 33 b.iter(|| { 34 let serialized = bincode::serialize(black_box(data)).unwrap(); 35 black_box(serialized) 36 }) 37 }, 38 ); 39 } 40 41 group.finish(); 42}

Allocation Benchmarking

rust
1#[cfg(test)] 2mod allocation_tests { 3 use super::*; 4 5 #[test] 6 fn test_zero_allocation_path() { 7 let allocations_before = allocation_counter::current(); 8 9 // Critical path that should not allocate 10 let result = process_request_zero_alloc(&input); 11 12 let allocations_after = allocation_counter::current(); 13 let total_allocations = allocations_after - allocations_before; 14 15 assert_eq!( 16 total_allocations, 0, 17 "Critical path allocated {} bytes", 18 total_allocations 19 ); 20 } 21}

Contract Testing

Trait Contract Tests

rust
1use async_trait::async_trait; 2 3#[async_trait] 4pub trait UserRepository: Send + Sync { 5 async fn get_user(&self, id: UserId) -> Result<User, RepositoryError>; 6 async fn save_user(&self, user: &User) -> Result<(), RepositoryError>; 7} 8 9/// Contract tests that all implementations must satisfy 10#[cfg(test)] 11pub mod contract_tests { 12 use super::*; 13 14 pub async fn test_user_repository_contract<R: UserRepository>(repo: R) { 15 // Test: Save and retrieve should be consistent 16 let user = User::new("test@example.com".to_string(), "Test User".to_string()); 17 18 repo.save_user(&user).await.unwrap(); 19 let retrieved = repo.get_user(user.id).await.unwrap(); 20 21 assert_eq!(user.id, retrieved.id); 22 assert_eq!(user.email, retrieved.email); 23 assert_eq!(user.name, retrieved.name); 24 } 25 26 pub async fn test_user_repository_not_found<R: UserRepository>(repo: R) { 27 // Test: Getting non-existent user should return error 28 let non_existent_id = UserId::new(); 29 let result = repo.get_user(non_existent_id).await; 30 31 assert!(matches!(result, Err(RepositoryError::NotFound))); 32 } 33} 34 35/// Apply contract tests to concrete implementation 36#[tokio::test] 37async fn postgres_repository_satisfies_contract() { 38 let repo = PostgresUserRepository::new(get_test_db().await); 39 contract_tests::test_user_repository_contract(repo.clone()).await; 40 contract_tests::test_user_repository_not_found(repo).await; 41} 42 43#[tokio::test] 44async fn in_memory_repository_satisfies_contract() { 45 let repo = InMemoryUserRepository::new(); 46 contract_tests::test_user_repository_contract(repo.clone()).await; 47 contract_tests::test_user_repository_not_found(repo).await; 48}

Miri for Undefined Behavior Detection

Using Miri

bash
1# Install Miri 2rustup +nightly component add miri 3 4# Run tests with Miri 5cargo +nightly miri test 6 7# Run specific test 8cargo +nightly miri test test_concurrent_access

Miri-Compatible Tests

rust
1#[cfg(test)] 2mod miri_tests { 3 use super::*; 4 5 #[test] 6 fn test_safe_concurrent_access() { 7 use std::sync::Arc; 8 use std::thread; 9 10 let counter = Arc::new(AtomicCounter::new()); 11 let mut handles = vec![]; 12 13 for _ in 0..10 { 14 let counter_clone = counter.clone(); 15 handles.push(thread::spawn(move || { 16 for _ in 0..100 { 17 counter_clone.increment(); 18 } 19 })); 20 } 21 22 for handle in handles { 23 handle.join().unwrap(); 24 } 25 26 assert_eq!(counter.get(), 1000); 27 } 28}

Table-Driven Tests

Data-Driven Test Cases

rust
1#[cfg(test)] 2mod table_driven_tests { 3 use super::*; 4 5 #[test] 6 fn test_email_validation() { 7 let test_cases = vec![ 8 ("test@example.com", true), 9 ("user+tag@domain.co.uk", true), 10 ("invalid.email", false), 11 ("@example.com", false), 12 ("user@", false), 13 ("", false), 14 ]; 15 16 for (input, expected_valid) in test_cases { 17 let result = Email::parse(input); 18 assert_eq!( 19 result.is_ok(), 20 expected_valid, 21 "Email validation failed for: {}", 22 input 23 ); 24 } 25 } 26 27 #[test] 28 fn test_status_code_mapping() { 29 let test_cases = vec![ 30 (ApiError::ValidationError(_), StatusCode::BAD_REQUEST), 31 (ApiError::Unauthorized, StatusCode::UNAUTHORIZED), 32 (ApiError::Forbidden, StatusCode::FORBIDDEN), 33 (ApiError::NotFound, StatusCode::NOT_FOUND), 34 (ApiError::InternalError, StatusCode::INTERNAL_SERVER_ERROR), 35 ]; 36 37 for (error, expected_status) in test_cases { 38 let status = error.status_code(); 39 assert_eq!( 40 status, expected_status, 41 "Status code mismatch for error: {:?}", 42 error 43 ); 44 } 45 } 46}

Best Practices

  1. Use property tests for invariant checking
  2. Fuzz parsers and deserializers extensively
  3. Benchmark hot paths with Criterion
  4. Write contract tests for trait implementations
  5. Run Miri on unsafe code and concurrent code
  6. Table-driven tests for comprehensive coverage
  7. Regression tests for bugs found in production
  8. Integration tests with real dependencies (testcontainers)

Common Dependencies

toml
1[dev-dependencies] 2proptest = "1" 3criterion = { version = "0.5", features = ["html_reports"] } 4testcontainers = "0.23" 5 6[dependencies] 7# For fuzz testing 8arbitrary = { version = "1", optional = true, features = ["derive"] } 9 10[features] 11fuzzing = ["arbitrary"]

CI Integration

yaml
1# Run all test suites in CI 2- name: Unit tests 3 run: cargo test --workspace 4 5- name: Property tests 6 run: cargo test --workspace -- --ignored proptest 7 8- name: Miri (UB detection) 9 run: | 10 rustup component add miri 11 cargo miri test 12 13- name: Benchmarks (smoke test) 14 run: cargo bench --no-run 15 16- name: Fuzz (smoke test) 17 run: | 18 cargo install cargo-fuzz 19 timeout 60s cargo fuzz run parse_input || true

Related Skills

Looking for an alternative to rust-testing-verification or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication