rust-testing

Rust testing patterns including unit tests, integration tests, async testing, property-based testing, mocking, and coverage. Follows TDD methodology.

144,923 stars
Complexity: easy

About this skill

This skill provides a comprehensive guide for AI agents to implement robust testing strategies in Rust projects. It covers a wide array of testing patterns including unit tests for individual components, integration tests for module interactions, async testing for concurrent code, property-based testing for input validation, and mocking for isolating dependencies. Emphasizing a Test-Driven Development (TDD) methodology, the skill guides the agent through defining target code and writing tests using `#[test]` and `rstest` macros, ensuring high-quality, maintainable, and reliable Rust code. It's an integral part of the 'everything-claude-code' repository, designed to enhance Claude's capabilities in software development best practices.

Best use case

Automating the creation of comprehensive and high-quality tests for Rust codebases, ensuring code reliability, maintainability, and adherence to TDD best practices.

Rust testing patterns including unit tests, integration tests, async testing, property-based testing, mocking, and coverage. Follows TDD methodology.

Well-structured, comprehensive Rust test suites generated according to TDD principles, covering various testing scenarios (unit, integration, async, property-based, mocking), leading to more reliable and maintainable Rust applications with improved code coverage.

Practical example

Example input

Generate unit tests for a Rust function that calculates the nth Fibonacci number, ensuring edge cases for n=0, n=1, and negative inputs are handled gracefully by returning an error.

Example output

```rust
#[cfg(test)]
mod tests {
    use super::fibonacci;

    #[test]
    fn test_fibonacci_zero() {
        assert_eq!(fibonacci(0), Ok(0));
    }

    #[test]
    fn test_fibonacci_one() {
        assert_eq!(fibonacci(1), Ok(1));
    }

    #[test]
    fn test_fibonacci_small_number() {
        assert_eq!(fibonacci(5), Ok(5)); // 0, 1, 1, 2, 3, 5
    }

    #[test]
    fn test_fibonacci_larger_number() {
        assert_eq!(fibonacci(10), Ok(55));
    }

    #[test]
    fn test_fibonacci_negative_input() {
        assert!(fibonacci(-1).is_err());
        assert_eq!(fibonacci(-1).unwrap_err().to_string(), "Input must be non-negative");
    }

    // Assuming the main function would look something like this:
    // pub fn fibonacci(n: i32) -> Result<u32, String> {
    //     if n < 0 {
    //         return Err("Input must be non-negative".to_string());
    //     }
    //     let n = n as u32;
    //     if n == 0 { 0 } else if n == 1 { 1 } else {
    //         let mut a = 0;
    //         let mut b = 1;
    //         for _ in 2..=n {
    //             let next = a + b;
    //             a = b;
    //             b = next;
    //         }
    //         b
    //     }.to_string()
    // }
}
```

When to use this skill

  • When developing new Rust features, functions, or traits; when enhancing existing Rust code with thorough test coverage; when establishing performance benchmarks; when applying property-based testing for robust input validation; or when strictly adhering to a Test-Driven Development (TDD) workflow in Rust projects.

When not to use this skill

  • When working with programming languages other than Rust, or when the goal is not to implement testing methodologies, but rather other development phases like initial feature implementation without immediate testing focus.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/rust-testing/SKILL.md --create-dirs "https://raw.githubusercontent.com/affaan-m/everything-claude-code/main/docs/tr/skills/rust-testing/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/rust-testing/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How rust-testing Compares

Feature / Agentrust-testingStandard Approach
Platform SupportClaudeLimited / Varies
Context Awareness High Baseline
Installation ComplexityeasyN/A

Frequently Asked Questions

What does this skill do?

Rust testing patterns including unit tests, integration tests, async testing, property-based testing, mocking, and coverage. Follows TDD methodology.

Which AI agents support this skill?

This skill is designed for Claude.

How difficult is it to install?

The installation complexity is rated as easy. You can find the installation instructions above.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Rust Test Desenleri

TDD metodolojisini takip ederek güvenilir, bakım yapılabilir testler yazmak için kapsamlı Rust test desenleri.

## Ne Zaman Kullanılır

- Yeni Rust fonksiyonları, metotları veya trait'leri yazma
- Mevcut koda test kapsamı ekleme
- Performans-kritik kod için benchmark'lar oluşturma
- Girdi doğrulama için property-based testler uygulama
- Rust projelerinde TDD iş akışını takip etme

## Nasıl Çalışır

1. **Hedef kodu tanımla** — Test edilecek fonksiyon, trait veya modülü bul
2. **Bir test yaz** — `#[cfg(test)]` modülünde `#[test]` kullan, parametreli testler için rstest veya property-based testler için proptest
3. **Bağımlılıkları mock'la** — Test altındaki birimi izole etmek için mockall kullan
4. **Testleri çalıştır (RED)** — Testin beklenen hata ile başarısız olduğunu doğrula
5. **Uygula (GREEN)** — Geçmek için minimal kod yaz
6. **Refactor** — Testleri yeşil tutarken iyileştir
7. **Kapsamı kontrol et** — cargo-llvm-cov kullan, 80%+ hedefle

## Rust için TDD İş Akışı

### RED-GREEN-REFACTOR Döngüsü

```
RED     → Önce başarısız bir test yaz
GREEN   → Testi geçmek için minimal kod yaz
REFACTOR → Testleri yeşil tutarken kodu iyileştir
REPEAT  → Bir sonraki gereksinimle devam et
```

### Rust'ta Adım-Adım TDD

```rust
// RED: Önce testi yaz, yer tutucu olarak todo!() kullan
pub fn add(a: i32, b: i32) -> i32 { todo!() }

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_add() { assert_eq!(add(2, 3), 5); }
}
// cargo test → 'not yet implemented'da panic
```

```rust
// GREEN: todo!()'yu minimal implementasyonla değiştir
pub fn add(a: i32, b: i32) -> i32 { a + b }
// cargo test → GEÇTİ, sonra testleri yeşil tutarken REFACTOR
```

## Unit Testler

### Modül Seviyesi Test Organizasyonu

```rust
// src/user.rs
pub struct User {
    pub name: String,
    pub email: String,
}

impl User {
    pub fn new(name: impl Into<String>, email: impl Into<String>) -> Result<Self, String> {
        let email = email.into();
        if !email.contains('@') {
            return Err(format!("invalid email: {email}"));
        }
        Ok(Self { name: name.into(), email })
    }

    pub fn display_name(&self) -> &str {
        &self.name
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn creates_user_with_valid_email() {
        let user = User::new("Alice", "alice@example.com").unwrap();
        assert_eq!(user.display_name(), "Alice");
        assert_eq!(user.email, "alice@example.com");
    }

    #[test]
    fn rejects_invalid_email() {
        let result = User::new("Bob", "not-an-email");
        assert!(result.is_err());
        assert!(result.unwrap_err().contains("invalid email"));
    }
}
```

### Assertion Makroları

```rust
assert_eq!(2 + 2, 4);                                    // Eşitlik
assert_ne!(2 + 2, 5);                                    // Eşitsizlik
assert!(vec![1, 2, 3].contains(&2));                     // Boolean
assert_eq!(value, 42, "expected 42 but got {value}");    // Özel mesaj
assert!((0.1_f64 + 0.2 - 0.3).abs() < f64::EPSILON);   // Float karşılaştırma
```

## Hata ve Panic Testi

### `Result` Dönüşlerini Test Etme

```rust
#[test]
fn parse_returns_error_for_invalid_input() {
    let result = parse_config("}{invalid");
    assert!(result.is_err());

    // Spesifik hata varyantını doğrula
    let err = result.unwrap_err();
    assert!(matches!(err, ConfigError::ParseError(_)));
}

#[test]
fn parse_succeeds_for_valid_input() -> Result<(), Box<dyn std::error::Error>> {
    let config = parse_config(r#"{"port": 8080}"#)?;
    assert_eq!(config.port, 8080);
    Ok(()) // Herhangi bir ? Err döndürürse test başarısız olur
}
```

### Panic'leri Test Etme

```rust
#[test]
#[should_panic]
fn panics_on_empty_input() {
    process(&[]);
}

#[test]
#[should_panic(expected = "index out of bounds")]
fn panics_with_specific_message() {
    let v: Vec<i32> = vec![];
    let _ = v[0];
}
```

## Entegrasyon Testleri

### Dosya Yapısı

```text
my_crate/
├── src/
│   └── lib.rs
├── tests/              # Entegrasyon testleri
│   ├── api_test.rs     # Her dosya ayrı bir test binary'si
│   ├── db_test.rs
│   └── common/         # Paylaşılan test yardımcıları
│       └── mod.rs
```

### Entegrasyon Testleri Yazma

```rust
// tests/api_test.rs
use my_crate::{App, Config};

#[test]
fn full_request_lifecycle() {
    let config = Config::test_default();
    let app = App::new(config);

    let response = app.handle_request("/health");
    assert_eq!(response.status, 200);
    assert_eq!(response.body, "OK");
}
```

## Async Testler

### Tokio ile

```rust
#[tokio::test]
async fn fetches_data_successfully() {
    let client = TestClient::new().await;
    let result = client.get("/data").await;
    assert!(result.is_ok());
    assert_eq!(result.unwrap().items.len(), 3);
}

#[tokio::test]
async fn handles_timeout() {
    use std::time::Duration;
    let result = tokio::time::timeout(
        Duration::from_millis(100),
        slow_operation(),
    ).await;

    assert!(result.is_err(), "should have timed out");
}
```

## Test Organizasyon Desenleri

### `rstest` ile Parametreli Testler

```rust
use rstest::{rstest, fixture};

#[rstest]
#[case("hello", 5)]
#[case("", 0)]
#[case("rust", 4)]
fn test_string_length(#[case] input: &str, #[case] expected: usize) {
    assert_eq!(input.len(), expected);
}

// Fixture'lar
#[fixture]
fn test_db() -> TestDb {
    TestDb::new_in_memory()
}

#[rstest]
fn test_insert(test_db: TestDb) {
    test_db.insert("key", "value");
    assert_eq!(test_db.get("key"), Some("value".into()));
}
```

### Test Yardımcıları

```rust
#[cfg(test)]
mod tests {
    use super::*;

    /// Mantıklı varsayılanlarla test kullanıcısı oluşturur.
    fn make_user(name: &str) -> User {
        User::new(name, &format!("{name}@test.com")).unwrap()
    }

    #[test]
    fn user_display() {
        let user = make_user("alice");
        assert_eq!(user.display_name(), "alice");
    }
}
```

## `proptest` ile Property-Based Testing

### Temel Property Testleri

```rust
use proptest::prelude::*;

proptest! {
    #[test]
    fn encode_decode_roundtrip(input in ".*") {
        let encoded = encode(&input);
        let decoded = decode(&encoded).unwrap();
        assert_eq!(input, decoded);
    }

    #[test]
    fn sort_preserves_length(mut vec in prop::collection::vec(any::<i32>(), 0..100)) {
        let original_len = vec.len();
        vec.sort();
        assert_eq!(vec.len(), original_len);
    }

    #[test]
    fn sort_produces_ordered_output(mut vec in prop::collection::vec(any::<i32>(), 0..100)) {
        vec.sort();
        for window in vec.windows(2) {
            assert!(window[0] <= window[1]);
        }
    }
}
```

### Özel Stratejiler

```rust
use proptest::prelude::*;

fn valid_email() -> impl Strategy<Value = String> {
    ("[a-z]{1,10}", "[a-z]{1,5}")
        .prop_map(|(user, domain)| format!("{user}@{domain}.com"))
}

proptest! {
    #[test]
    fn accepts_valid_emails(email in valid_email()) {
        assert!(User::new("Test", &email).is_ok());
    }
}
```

## `mockall` ile Mock'lama

### Trait-Tabanlı Mock'lama

```rust
use mockall::{automock, predicate::eq};

#[automock]
trait UserRepository {
    fn find_by_id(&self, id: u64) -> Option<User>;
    fn save(&self, user: &User) -> Result<(), StorageError>;
}

#[test]
fn service_returns_user_when_found() {
    let mut mock = MockUserRepository::new();
    mock.expect_find_by_id()
        .with(eq(42))
        .times(1)
        .returning(|_| Some(User { id: 42, name: "Alice".into() }));

    let service = UserService::new(Box::new(mock));
    let user = service.get_user(42).unwrap();
    assert_eq!(user.name, "Alice");
}

#[test]
fn service_returns_none_when_not_found() {
    let mut mock = MockUserRepository::new();
    mock.expect_find_by_id()
        .returning(|_| None);

    let service = UserService::new(Box::new(mock));
    assert!(service.get_user(99).is_none());
}
```

## Doc Testleri

### Çalıştırılabilir Dokümantasyon

```rust
/// İki sayıyı toplar.
///
/// # 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
}

/// Bir config string'i parse eder.
///
/// # Errors
///
/// Girdi geçerli TOML değilse `Err` döner.
///
/// ```no_run
/// use my_crate::parse_config;
///
/// let config = parse_config(r#"port = 8080"#).unwrap();
/// assert_eq!(config.port, 8080);
/// ```
///
/// ```no_run
/// use my_crate::parse_config;
///
/// assert!(parse_config("}{invalid").is_err());
/// ```
pub fn parse_config(input: &str) -> Result<Config, ParseError> {
    todo!()
}
```

## Criterion ile Benchmark'lama

```toml
# Cargo.toml
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }

[[bench]]
name = "benchmark"
harness = false
```

```rust
// benches/benchmark.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn fibonacci(n: u64) -> u64 {
    match n {
        0 | 1 => n,
        _ => fibonacci(n - 1) + fibonacci(n - 2),
    }
}

fn bench_fibonacci(c: &mut Criterion) {
    c.bench_function("fib 20", |b| b.iter(|| fibonacci(black_box(20))));
}

criterion_group!(benches, bench_fibonacci);
criterion_main!(benches);
```

## Test Kapsamı

### Kapsamı Çalıştırma

```bash
# Kurulum: cargo install cargo-llvm-cov (veya CI'da taiki-e/install-action kullan)
cargo llvm-cov                    # Özet
cargo llvm-cov --html             # HTML raporu
cargo llvm-cov --lcov > lcov.info # CI için LCOV formatı
cargo llvm-cov --fail-under-lines 80  # Eşiğin altındaysa başarısız yap
```

### Kapsam Hedefleri

| Kod Tipi | Hedef |
|----------|-------|
| Kritik iş mantığı | 100% |
| Public API | 90%+ |
| Genel kod | 80%+ |
| Oluşturulmuş / FFI binding'leri | Hariç tut |

## Test Komutları

```bash
cargo test                        # Tüm testleri çalıştır
cargo test -- --nocapture         # println çıktısını göster
cargo test test_name              # Desene uyan testleri çalıştır
cargo test --lib                  # Sadece unit testler
cargo test --test api_test        # Sadece entegrasyon testleri
cargo test --doc                  # Sadece doc testleri
cargo test --no-fail-fast         # İlk başarısızlıkta durma
cargo test -- --ignored           # Yok sayılan testleri çalıştır
```

## En İyi Uygulamalar

**YAPIN:**
- ÖNCE testleri yazın (TDD)
- Unit testler için `#[cfg(test)]` modülleri kullanın
- Implementasyon değil, davranışı test edin
- Senaryoyu açıklayan açıklayıcı test isimleri kullanın
- Daha iyi hata mesajları için `assert!` yerine `assert_eq!` tercih edin
- Daha temiz hata çıktısı için `Result` döndüren testlerde `?` kullanın
- Testleri bağımsız tutun — paylaşılan mutable state yok

**YAPMAYIN:**
- `Result::is_err()` test edebiliyorsanız `#[should_panic]` kullanmayın
- Her şeyi mock'lamayın — mümkün olduğunda entegrasyon testlerini tercih edin
- Kararsız testleri yok saymayın — düzeltin veya karantinaya alın
- Testlerde `sleep()` kullanmayın — channel'lar, barrier'lar veya `tokio::time::pause()` kullanın
- Hata yolu testini atlamayın

## CI Entegrasyonu

```yaml
# GitHub Actions
test:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
      with:
        components: clippy, rustfmt

    - name: Check formatting
      run: cargo fmt --check

    - name: Clippy
      run: cargo clippy -- -D warnings

    - name: Run tests
      run: cargo test

    - uses: taiki-e/install-action@cargo-llvm-cov

    - name: Coverage
      run: cargo llvm-cov --fail-under-lines 80
```

**Unutmayın**: Testler dokümantasyondur. Kodunuzun nasıl kullanılması gerektiğini gösterirler. Onları net yazın ve güncel tutun.

Related Skills

swift-protocol-di-testing

144923
from affaan-m/everything-claude-code

基于协议的依赖注入,用于可测试的Swift代码——使用聚焦协议和Swift Testing模拟文件系统、网络和外部API。

DevelopmentClaude

perl-testing

144923
from affaan-m/everything-claude-code

使用Test2::V0、Test::More、prove runner、模拟、Devel::Cover覆盖率和TDD方法的Perl测试模式。

DevelopmentClaude

rust-patterns

144923
from affaan-m/everything-claude-code

Idiomatic Rust patterns, ownership, error handling, traits, concurrency, and best practices for building safe, performant applications.

DevelopmentClaude

kotlin-testing

144923
from affaan-m/everything-claude-code

Kotest, MockK, coroutine testi, property-based testing ve Kover coverage ile Kotlin test kalıpları. İdiomatic Kotlin uygulamalarıyla TDD metodolojisini takip eder.

DevelopmentClaude

cpp-testing

144923
from affaan-m/everything-claude-code

C++ テストの作成/更新/修正、GoogleTest/CTest の設定、失敗またはフレーキーなテストの診断、カバレッジ/サニタイザーの追加時にのみ使用します。

DevelopmentClaude

python-testing

144923
from affaan-m/everything-claude-code

Python testing best practices using pytest including fixtures, parametrization, mocking, coverage analysis, async testing, and test organization. Use when writing or improving Python tests.

DevelopmentClaude

golang-testing

144923
from affaan-m/everything-claude-code

Go testing best practices including table-driven tests, test helpers, benchmarking, race detection, coverage analysis, and integration testing patterns. Use when writing or improving Go tests.

DevelopmentClaude

workspace-surface-audit

144923
from affaan-m/everything-claude-code

Audit the active repo, MCP servers, plugins, connectors, env surfaces, and harness setup, then recommend the highest-value ECC-native skills, hooks, agents, and operator workflows. Use when the user wants help setting up Claude Code or understanding what capabilities are actually available in their environment.

DevelopmentClaude

safety-guard

144923
from affaan-m/everything-claude-code

Use this skill to prevent destructive operations when working on production systems or running agents autonomously.

DevelopmentClaude

repo-scan

144923
from affaan-m/everything-claude-code

Cross-stack source code asset audit — classifies every file, detects embedded third-party libraries, and delivers actionable four-level verdicts per module with interactive HTML reports.

DevelopmentClaude

project-flow-ops

144923
from affaan-m/everything-claude-code

Operate execution flow across GitHub and Linear by triaging issues and pull requests, linking active work, and keeping GitHub public-facing while Linear remains the internal execution layer. Use when the user wants backlog control, PR triage, or GitHub-to-Linear coordination.

DevelopmentClaude

manim-video

144923
from affaan-m/everything-claude-code

Build reusable Manim explainers for technical concepts, graphs, system diagrams, and product walkthroughs, then hand off to the wider ECC video stack if needed. Use when the user wants a clean animated explainer rather than a generic talking-head script.

DevelopmentClaude