关于 rust-testing
面向 Rust 开发者的测试指导 Skill,涵盖单元、集成、文档、异步和属性测试,并提供运行及覆盖率命令。
主要功能
- 01单元与集成测试模式
- 02文档测试示例
- 03使用 tokio 编写异步测试
- 04使用 proptest 进行属性测试
- 05覆盖率命令
适用场景
- 01为 Rust 模块添加单元测试
- 02通过集成测试验证 API
- 03检查异步操作与超时
- 04测量测试覆盖率
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ autumnsgrove/ lattice --skill rust-testing安装后在 Claude Code 中输入/rust-testing确认已加载。
详细介绍
Rust 测试技能
何时启用
在以下情况启用此技能:
- 编写 Rust 单元测试
- 创建集成测试
- 编写文档测试
- 设置基于属性的测试
- 运行基准测试
快速命令
# Run all tests
cargo test
# With output
cargo test -- --nocapture
# Run specific test
cargo test test_user_create
# Run tests in module
cargo test auth::
# Run ignored tests
cargo test -- --ignored
# Doc tests only
cargo test --doc
# Integration tests only
cargo test --test integration
单元测试(同一文件)
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn test_add_negative() {
assert_eq!(add(-1, -1), -2);
}
}
测试属性
#[test]
fn regular_test() { }
#[test]
#[ignore]
fn slow_test() { } // Skip unless --ignored
#[test]
#[should_panic]
fn test_panic() {
panic!("This should panic");
}
#[test]
#[should_panic(expected = "specific message")]
fn test_panic_message() {
panic!("specific message here");
}
#[test]
fn test_with_result() -> Result<(), String> {
let result = some_operation()?;
assert_eq!(result, expected);
Ok(())
}
断言
// Basic
assert_eq!(1 + 1, 2);
assert_ne!(1 + 1, 3);
assert!(true);
// With messages
assert_eq!(result, expected, "values should match: got {}", result);
// Pattern matching
assert!(matches!(value, Pattern::Variant(_)));
// Option/Result
assert!(some_option.is_some());
assert!(some_result.is_ok());
集成测试
// tests/api_integration.rs
use my_crate::{Config, Server};
#[test]
fn test_server_startup() {
let config = Config::default();
let server = Server::new(config);
assert!(server.start().is_ok());
}
目录结构
project/
├── Cargo.toml
├── src/
│ ├── lib.rs # Unit tests in #[cfg(test)]
│ └── user.rs # Module with inline tests
└── tests/ # Integration tests
├── common/
│ └── mod.rs # Shared utilities
└── api_test.rs
使用 Trait 进行模拟
pub trait UserRepository {
fn find_by_id(&self, id: u64) -> Option<User>;
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
struct MockUserRepo {
users: HashMap<u64, User>,
}
impl UserRepository for MockUserRepo {
fn find_by_id(&self, id: u64) -> Option<User> {
self.users.get(&id).cloned()
}
}
#[test]
fn test_user_service() {
let mut users = HashMap::new();
users.insert(1, User { id: 1, email: "[email protected]".into() });
let repo = MockUserRepo { users };
let service = UserService::new(Box::new(repo));
let user = service.get_user(1).unwrap();
assert_eq!(user.email, "[email protected]");
}
}
异步测试(tokio)
#[tokio::test]
async fn test_async_operation() {
let result = fetch_data().await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_with_timeout() {
let result = tokio::time::timeout(
Duration::from_secs(5),
slow_operation()
).await;
assert!(result.is_ok());
}
文档测试
/// Adds two numbers together.
///
/// # Examples
///
/// ```
/// use my_crate::add;
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
基于属性的测试(proptest)
use proptest::prelude::*;
proptest! {
#[test]
fn test_add_commutative(a: i32, b: i32) {
prop_assert_eq!(add(a, b), add(b, a));
}
}
覆盖率
# Using cargo-tarpaulin
cargo install cargo-tarpaulin
cargo tarpaulin --out Html
# Using cargo-llvm-cov
cargo install cargo-llvm-cov
cargo llvm-cov --html
相关资源
请参阅 AgentUsage/testing_rust.md,获取完整文档,其中包括:
- 使用 criterion 进行基准测试
- 设置/清理模式
- Mockall crate 的用法
- CI 配置
评论
支持 Markdown