rust-testing について
Rust 開発者向けに、テスト設計、実行、ベンチマーク、カバレッジを扱うスキルです。安定版 Rust の手法に加え、並行処理やプラットフォーム別の検証を重視します。
主な機能
- 01ユニット、統合、ドキュメントテスト
- 02cargo test の絞り込みと実行オプション
- 03Criterion による安定版ベンチマーク
- 04cargo-llvm-cov によるカバレッジ確認
- 05並行処理とプラットフォームの検証
活用シーン
- 01Rust モジュールやクレートへのテスト追加
- 02tests/ での統合テストの構成
- 03実行可能な例を使った API ドキュメント作成
- 04カバレッジやベンチマーク性能の測定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ full-stack-skills/ rust-skills --skill rust-testingインストール後、Claude Code で/rust-testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlexamples/examples.mdexamples/golden-tests/Cargo.tomlexamples/golden-tests/src/lib.rsreferences/concurrency-daemon-platform-testing.mdreferences.md詳細
Rust のテストとベンチマーク
The Rust Programming Language の第11章および Rust Book に基づいています。
対応範囲
✅ 得意分野
- ユニットテスト(
#[test]の使用、#[cfg(test)]によるテストモジュールの構成) - アサーションマクロ(
assert!、assert_eq!、assert_ne!、debug_assert!) - テスト属性(
#[should_panic]、#[ignore]、#[cfg(test)]) - 統合テスト(tests/ ディレクトリと共有モジュール)
- ドキュメントテスト(コードブロック、
#による非表示行、should_panic/no_run/ignore フラグ) - cargo test ランナー(フィルタリング、--nocapture、--test-threads、--include-ignored オプション)
- 安定版の Criterion ベンチマーク。安定版の Criterion と nightly 専用の libtest
#[bench]属性を明確に区別します - cargo-llvm-cov によるコードカバレッジ
- 非同期の競合状態、バックプレッシャー、タイムアウト、プロセス/デーモンモデル、プラットフォームマトリックス、リソース制約下でのテスト
⚠️ 前提条件
- Rust のモジュールシステムの理解(rust-workspace)
❌ 対象外
- プロパティベーステスト(
proptest)→ 現在は対象外です - モックオブジェクト → 現在は対象外です
- Rust の基本構文 →
rust-stableスキルを使用してください
使用する場面
- 「ユニットテストを書く」
- 「統合テストはどこに配置すればよいですか?」
- 「ドキュメントテストはどのように書けばよいですか?」
- 「パフォーマンスのベンチマーク」
- 「コードカバレッジを確認する」
振り分けの境界
テストで Java のソーステストスイートを振り分ける必要がある場合、ミラーされたテストとゴールデン/ライブ差分エビデンスを区別する場合、ターゲット固有の所有権/非同期/エラー/コンポーネントに関する要件を追加する場合、カバレッジを追い求めるテストを監査する場合、または移行のライフサイクル/アダプター/ホストの受け入れを検証する場合は、rust-java-migration-testing を使用してください。このスキルは、Rust の一般的なテストの仕組みと Rust ネイティブのテストアーキテクチャに焦点を当てます。
ユニットテスト
// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 { a + b }
pub fn divide(a: i32, b: i32) -> i32 {
if b == 0 { panic!("divide by zero"); }
a / b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 2), 4);
}
#[test]
fn test_add_negative() {
assert_eq!(add(-1, 1), 0, "addition with negative");
}
#[test]
#[should_panic(expected = "divide by zero")]
fn test_divide_by_zero() {
divide(1, 0);
}
#[test]
#[ignore = "not implemented"]
fn test_future() { unimplemented!() }
}
統合テスト
my-project/
├── Cargo.toml
├── src/lib.rs
└── tests/
├── common/ # Test shared modules
│ └── mod.rs
├── integration_test.rs
└── api_test.rs
// tests/integration_test.rs — Each file is an independent crate
use my_project::add;
#[test]
fn integration_test() {
assert_eq!(add(1, 2), 3);
}
// tests/common/mod.rs — Shared helper functions
pub fn setup() { /* ... */ }
ドキュメントテスト(doctest)
/// Add two numbers.
///
/// ```
/// use my_crate::add;
/// assert_eq!(add(2, 3), 5);
/// ```
///
/// ```rust,should_panic
/// my_crate::divide(1, 0);
/// ```
///
/// ```rust,no_run
/// // Compile but do not run
/// loop {}
/// ```
pub fn add(a: i32, b: i32) -> i32 { a + b }
cargo test コマンド
cargo test # Run all tests
cargo test test_name # Filter by name
cargo test -- --nocapture # Show println output
cargo test -- --test-threads=1 # Single thread
cargo test -- --skip test_name # Skip specific tests
cargo test -- --ignored # Only run #[ignore] tests
cargo test -- --include-ignored # Include ignored tests
cargo test --doc # Run only documentation tests
cargo test -p my-crate # Specific package
ベンチマーク
安定版のプロジェクトでは Criterion を優先してください。組み込みの libtest #[bench] は引き続き nightly の #![feature(test)] に依存しており、安定版でのデフォルトの解決策としては使用できません。
// Nightly-only builtin approach (do not use for stable gatekeeping)
#![feature(test)]
extern crate test;
#[cfg(test)]
mod benches {
use test::Bencher;
use super::*;
#[bench]
fn bench_add(b: &mut Bencher) {
b.iter(|| add(1, 2));
}
}
// Stable approach using criterion
// [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] }
use criterion::{black_box, Criterion};
fn bench_add(c: &mut Criterion) {
c.bench_function("add", |b| b.iter(|| add(black_box(1), black_box(2))));
}
criterion_group!(benches, bench_add);
criterion_main!(benches);
コードカバレッジ
# Install
cargo install cargo-llvm-cov
# Usage
cargo llvm-cov # Run and report results
cargo llvm-cov --open # Generate HTML reports
cargo llvm-cov --lcov --output-path lcov.info # LCOV format output
ワークフロー
- テスト環境を準備する — cargo test が利用可能であることを確認し、テストの種類(ユニット/統合/ドキュメント)を確認します
- ユニットテストを書く —
#[cfg(test)]モジュール内に#[test]関数を実装します - 統合テストを追加する — tests/ ディレクトリに独立したクレート型のファイルを作成します
- ドキュメントテストを追加する — /// コメント内に実行可能なコードブロックを埋め込みます
- 実行してデバッグする — cargo test を使用します。問題の特定には --nocapture を使用します。共有リソースについては、テストスイート全体を恒久的に直列化するのではなく、リソースの分離またはテストのグループ化を優先します
- 並行処理とプラットフォームを検証する — 実際のターゲットプラットフォームで、キューの上限、低速なコンシューマー、切断、キャンセル、タイムアウト、正常なシャットダウンに対する範囲を限定したアサーションを実装します。プラットフォーム固有のコードは直接実行します
- カバレッジを確認する — cargo llvm-cov を使用してカバレッジの範囲を検証します
注意点
#[cfg(test)]モジュール内のコードはリリースビルドにはコンパイルされません — ヘルパー関数は tests/common/mod.rs に置いてください- 統合テストのファイルは独立したクレートです — その中では super:: や crate:: のプレフィックスを使用できません
- ドキュメントテスト内の非表示行(#)は、コンパイラーには見えませんが実行されます
- cargo test はデフォルトで並列実行されます。共有リソースの競合は、一意な一時ディレクトリ/ポート、プロセスの分離、nextest のテストグループ制限、または必要な場合に限ったローカルな直列化によって解決してください
- #[bench] には #![feature(test)] が必要です — 安定版 Rust では代わりに criterion を使用してください
- 非同期テストに広いタイムアウトを設定すると、デッドロックの原因が見えにくくなります。中間状態、タスクの復旧、リソース数もアサートしてください
オンデマンドリソース
- テスト例
- マクロコマンドとコマンドリファレンス
- 並行処理、デーモン、プラットフォームのテスト:タスク内のメモリリーク、処理の遅いコンシューマー、競合状態、実際のプロセス、読み取り時のリソース制限付き並列処理をテストします。
examples/golden-tests/:doctest のゴールデン例を CI でコンパイルおよび実行します
公式リファレンス
コメント
Markdown 対応