rust-async-testing について
Tokio を使う Rust の非同期コード向けテストパターン集です。テストランタイム、時間制御、並行処理、タイムアウト、メモリのライフサイクル検証を扱います。
主な機能
- 01Tokio 非同期テストの設定
- 02時間を一時停止するテスト
- 03マルチスレッド並行テスト
- 04タイムアウトとエラー経路のテスト
- 05非同期メモリのライフサイクルパターン
活用シーン
- 01Tokio ベースの非同期関数のテスト
- 02実際の待機なしで時間依存動作を確認
- 03並行タスクと共有状態の検証
- 04メモリエピソードのライフサイクル操作の検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ d-o-hub/ rust-self-learning-memory --skill rust-async-testingインストール後、Claude Code で/rust-async-testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
resources/concurrent-ops.mdmock-storage.mdtokio-patterns.md詳細
Rust の非同期テストパターン
Tokio で Rust の非同期コードをテストするためのベストプラクティスです。
基本パターン
基本的な非同期テスト
#[tokio::test]
async fn test_episode_creation() {
let memory = SelfLearningMemory::new(Default::default()).await?;
let id = memory.start_episode("Test", ctx, TaskType::CodeGen).await;
assert!(!id.is_empty());
}
時間ベースのテスト
#[tokio::test(start_paused = true)]
async fn test_timeout_behavior() {
// Time advances only when awaited
let start = tokio::time::Instant::now();
tokio::time::sleep(Duration::from_secs(5)).await;
assert!(start.elapsed().as_millis() < 100);
}
並行処理
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn test_concurrent_episodes() {
let memory = Arc::new(setup_memory().await);
let handles: Vec<_> = (0..10).map(|i| {
let mem = memory.clone();
tokio::spawn(async move {
mem.start_episode(format!("Task {}", i), ctx, type_).await
})
}).collect();
let results = futures::future::join_all(handles).await;
assert_eq!(results.len(), 10);
}
タイムアウトのテスト
#[tokio::test]
async fn test_operation_timeout() {
let result = tokio::time::timeout(
Duration::from_secs(2),
slow_operation()
).await;
assert!(result.is_err());
}
ベストプラクティス
block_onではなく#[tokio::test]を使用します- 時間のテストでは
start_paused = trueを有効にします - 並行処理のテストでは
multi_threadを使用します - 外部依存関係をモックします
- エラーパスをテストします
よくある落とし穴
| 悪い例 | 良い例 |
|---|---|
std::thread::sleep() | tokio::time::sleep().await |
memory.start_episode() | memory.start_episode().await |
| 並行処理にシングルスレッドを使用 | multi_thread ランタイム |
メモリ固有のパターン
#[tokio::test]
async fn test_complete_lifecycle() {
let memory = setup_memory().await;
// Start → Log Steps → Complete → Verify
let id = memory.start_episode("test", ctx, type_).await;
memory.log_execution_step(id.clone(), step).await;
memory.complete_episode(id.clone(), outcome, None).await?;
let episode = memory.get_episode(&id).await?;
assert_eq!(episode.outcome, outcome);
}
コメント
Markdown 対応