About rust-async-testing
A reference skill for testing asynchronous Rust code with Tokio. It covers test runtimes, time control, concurrency, timeouts, and memory-oriented lifecycle tests.
Key features
- 01Tokio async test setup
- 02Paused-time tests
- 03Multi-threaded concurrency tests
- 04Timeout and error-path testing
- 05Async memory lifecycle pattern
Use cases
- 01Testing Tokio-based async functions
- 02Checking time-dependent behavior without real delays
- 03Exercising concurrent tasks and shared state
- 04Verifying memory episode lifecycle operations
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ d-o-hub/ rust-self-learning-memory --skill rust-async-testingAfter installing, type/rust-async-testingin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
resources/concurrent-ops.mdmock-storage.mdtokio-patterns.mdDetails
From the project READMERust Async Testing Patterns
Best practices for testing async Rust code with Tokio.
Core Patterns
Basic Async Test
#[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());
}
Time-Based Testing
#[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);
}
Concurrent Operations
#[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);
}
Timeout Testing
#[tokio::test]
async fn test_operation_timeout() {
let result = tokio::time::timeout(
Duration::from_secs(2),
slow_operation()
).await;
assert!(result.is_err());
}
Best Practices
- Use
#[tokio::test]instead ofblock_on - Enable
start_paused = truefor time tests - Use
multi_threadfor concurrency tests - Mock external dependencies
- Test error paths
Common Pitfalls
| Bad | Good |
|---|---|
std::thread::sleep() | tokio::time::sleep().await |
memory.start_episode() | memory.start_episode().await |
| Single-threaded for concurrency | multi_thread runtime |
Memory-Specific Pattern
#[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);
}
Comments
Markdown supported