用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tomevault-io/skills-registry --skill rust-testing命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
| Use when this capability is needed.
> Use when this capability is needed.
Review architecture and API design for the vfs-s3 project. Use when the user mentions @architect, asks to review an issue's design, discuss module boundaries, API shape, or architectural decisions for vfs-s3. Also trigger when the user wants to create an ADR (Architecture Decision Record) or evaluate a technical approach for the project. Intended for dispatch from Codex automation or Claude routines; GitHub trigger phrase: @vfs-s3-bot please prepare design doc Use when this capability is needed.
基于 SOC 职业分类
正在显示 SKILL.md
| name | rust-testing |
| description | | Use when this capability is needed. |
Deep Knowledge: Use
mcp__documentation__fetch_docswith technology:rustfor comprehensive documentation.
Full Reference: See advanced.md for HTTP Testing with wiremock, Property-Based Testing with proptest, Benchmarks with criterion, and Test Coverage with cargo-tarpaulin.
vitest or jestjunit for Java testingpytest for Pythongo-testing skill// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
pub fn divide(a: f64, b: f64) -> Option<f64> {
if b == 0.0 {
None
} else {
Some(a / b)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn test_divide() {
assert_eq!(divide(10.0, 2.0), Some(5.0));
}
#[test]
fn test_divide_by_zero() {
assert_eq!(divide(10.0, 0.0), None);
}
}
# Run all tests
cargo test
# Run specific test
cargo test test_add
# Run tests in specific module
cargo test tests::
# Run tests with output
cargo test -- --nocapture
# Run tests sequentially
cargo test -- --test-threads=1
# Run ignored tests
cargo test -- --ignored
#[cfg(test)]
mod tests {
#[test]
fn test_assertions() {
// Equality
assert_eq!(2 + 2, 4);
assert_ne!(2 + 2, 5);
// Boolean
assert!(true);
assert!(!false);
// Custom message
assert!(1 + 1 == 2, "Math is broken!");
assert_eq!(2 + 2, 4, "Expected {} but got {}", 4, 2 + 2);
}
#[test]
fn test_floating_point() {
let result = 0.1 + 0.2;
let expected = 0.3;
// Approximate comparison for floats
assert!((result - expected).abs() < 1e-10);
}
}
pub fn divide_or_panic(a: i32, b: i32) -> i32 {
if b == 0 {
panic!("Cannot divide by zero!");
}
a / b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_panic() {
divide_or_panic(10, 0);
}
#[test]
#[should_panic(expected = "Cannot divide by zero")]
fn test_panic_message() {
divide_or_panic(10, 0);
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_with_result() -> Result<(), String> {
if 2 + 2 == 4 {
Ok(())
} else {
Err("Math failed".to_string())
}
}
}
#[test]
#[ignore]
fn expensive_test() {
// Long running test
std::thread::sleep(std::time::Duration::from_secs(60));
}
#[test]
#[ignore = "requires database connection"]
fn test_database() {
// Test that requires external resources
}
// tests/integration_test.rs
use my_crate::{add, divide};
#[test]
fn test_add_integration() {
assert_eq!(add(100, 200), 300);
}
// tests/common/mod.rs - Shared test utilities
pub fn setup() {
// Setup code
}
// tests/another_test.rs
mod common;
#[test]
fn test_with_setup() {
common::setup();
// Test code
}
# Cargo.toml
[dev-dependencies]
tokio = { version = "1", features = ["full", "test-util"] }
use tokio::time::{sleep, Duration};
async fn async_add(a: i32, b: i32) -> i32 {
sleep(Duration::from_millis(10)).await;
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_async_add() {
let result = async_add(2, 3).await;
assert_eq!(result, 5);
}
#[tokio::test]
async fn test_multiple_async() {
let (a, b) = tokio::join!(
async_add(1, 2),
async_add(3, 4)
);
assert_eq!(a, 3);
assert_eq!(b, 7);
}
}
use tokio::time::{self, Duration, Instant};
async fn delayed_operation() -> &'static str {
time::sleep(Duration::from_secs(10)).await;
"done"
}
#[cfg(test)]
mod tests {
use super::*;
use tokio::time::{pause, advance};
#[tokio::test]
async fn test_with_time_control() {
pause(); // Pause time
let start = Instant::now();
let future = delayed_operation();
// Advance time instantly
advance(Duration::from_secs(10)).await;
let result = future.await;
assert_eq!(result, "done");
// Very little real time has passed
assert!(start.elapsed() < Duration::from_secs(1));
}
}
# Cargo.toml
[dev-dependencies]
mockall = "0.12"
use mockall::{automock, predicate::*};
#[automock]
trait Database {
fn get(&self, key: &str) -> Option<String>;
fn set(&mut self, key: &str, value: &str) -> bool;
}
struct Service<D: Database> {
db: D,
}
impl<D: Database> Service<D> {
fn new(db: D) -> Self {
Self { db }
}
fn get_value(&self, key: &str) -> String {
self.db.get(key).unwrap_or_else(|| "default".to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_value_exists() {
let mut mock = MockDatabase::new();
mock.expect_get()
.with(eq())
.()
.(|_| (.()));
= Service::(mock);
(service.(), );
}
() {
= MockDatabase::();
mock.()
.(())
.()
.(|_| );
= Service::(mock);
(service.(), );
}
}
#[cfg(test)]
mod tests {
use super::*;
use mockall::Sequence;
#[test]
fn test_call_count() {
let mut mock = MockDatabase::new();
mock.expect_get()
.times(3) // Exactly 3 times
.returning(|_| Some("value".to_string()));
let service = Service::new(mock);
service.get_value("a");
service.get_value("b");
service.get_value("c");
}
#[test]
fn test_call_sequence() {
let mut seq = Sequence::new();
let mut mock = MockDatabase::new();
mock.expect_get()
.with(eq("first"))
.times(1)
.in_sequence(& seq)
.(|_| (.()));
mock.()
.(())
.()
.(& seq)
.(|_| (.()));
= Service::(mock);
(service.(), );
(service.(), );
}
}
use mockall::{automock, predicate::*};
use async_trait::async_trait;
#[async_trait]
#[automock]
trait AsyncDatabase {
async fn get(&self, key: &str) -> Option<String>;
async fn set(&self, key: &str, value: &str) -> bool;
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_async_mock() {
let mut mock = MockAsyncDatabase::new();
mock.expect_get()
.with(eq("key"))
.times(1)
.returning(|_| Some("value".to_string()));
let result = mock.get("key").await;
assert_eq!(result, Some(.()));
}
}
| Anti-Pattern | Why It's Bad | Solution |
|---|---|---|
| Testing private functions | Coupled to implementation | Test through public API |
| Not using #[should_panic] | Missing error validation | Test expected panics explicitly |
| Shared mutable state in tests | Flaky tests | Use test isolation |
| Not using Result<()> in tests | Can't use ? operator | Return Result<(), Error> |
| Ignoring async tests | Wrong runtime behavior | Use #[tokio::test] for async |
| Not benchmarking | Performance regressions | Use Criterion for benchmarks |
| Missing property tests | Edge cases missed | Use proptest for algorithms |
| Problem | Likely Cause | Solution |
|---|---|---|
| "test result: FAILED. 0 passed" | Panic in test | Check panic message, add proper assertions |
| Async test timeout | Missing await or infinite loop | Ensure all futures are awaited |
| Mock expectation failed | Wrong method calls | Verify mockall expectations |
| "cannot find derive macro" | Missing dev-dependency | Add mockall to [dev-dependencies] |
| Benchmark not running | Wrong harness setting | Set harness = false in [[bench]] |
| Coverage tool crashes | Incompatible version | Use cargo-tarpaulin or llvm-cov |
Source: claude-dev-suite/claude-dev-suite — distributed by TomeVault.