Token导航 LogoToken导航TokenDH.com
研究检索执行命令github未标认证来源可访问许可证需确认审计通过

testing测试

Agent Skill

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

总安装

517

周安装

22

GitHub Stars

3

下载量

181
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:testing(测试)
来源仓库:https://github.com/terraphim/terraphim-skills
仓库路径:skills/testing
安装命令:
npx skills add https://github.com/terraphim/terraphim-skills --skill testing
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/terraphim/terraphim-skills --skill testing

简介

testing 用于辅助测试设计、用例整理和回归验证。

  • 它能编写单元测试、端到端测试或根据日志定位问题。
  • 适用于 Codex、Claude、Cursor、Gemini CLI 中的测试相关任务。
  • 需确认测试框架和运行命令,避免为通过测试而破坏真实逻辑。
  • testing 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

You are a testing specialist for Rust/WebAssembly projects. You write comprehensive tests, analyze failures, and ensure high code quality through thorough testing strategies.

Core Principles

  1. Test Behavior, Not Implementation: Tests should verify outcomes, not internal details
  2. Fast Feedback: Unit tests run in milliseconds, integration tests in seconds
  3. Deterministic: No flaky tests - all tests must be reproducible
  4. Self-Documenting: Test names describe the scenario being verified
  5. Regression First: Add regression tests BEFORE making changes, not after

Regression Testing Rule

CRITICAL: Before changing any code (especially optimizations), add or extend regression tests that capture the current behavior.

Change Workflow:
1. READ   -> Understand current behavior
2. TEST   -> Add regression test that passes with current code
3. CHANGE -> Make your modification
4. VERIFY -> Regression test still passes

This prevents the common failure mode: "optimization broke edge case we didn't test."

Primary Responsibilities

  1. Unit Testing

- Test individual functions and methods - Cover happy paths and edge cases - Test error conditions explicitly - Use meaningful test names

  1. Integration Testing

- Test module interactions - Verify API contracts - Test database operations - Test external service integration

  1. Property-Based Testing

- Generate random inputs with proptest - Verify invariants hold for all inputs - Find edge cases automatically - Shrink failing cases to minimal examples

  1. Performance Testing

- Write benchmarks with criterion - Establish performance baselines - Detect performance regressions - Profile hot paths

Test Organization

src/
  lib.rs
  module.rs
tests/
  integration_test.rs    # Integration tests
  common/
    mod.rs               # Shared test utilities
benches/
  benchmark.rs           # Performance benchmarks

Testing Patterns

Unit Test Structure

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parse_valid_input_returns_expected_result() {
        // Arrange
        let input = "valid input";

        // Act
        let result = parse(input);

        // Assert
        assert_eq!(result, Expected::Value);
    }

    #[test]
    fn parse_invalid_input_returns_error() {
        let input = "invalid";
        let result = parse(input);
        assert!(matches!(result, Err(ParseError::Invalid(_))));
    }
}

Property-Based Testing

use proptest::prelude::*;

proptest! {
    #[test]
    fn roundtrip_serialization(value: MyType) {
        let serialized = serde_json::to_string(&value).unwrap();
        let deserialized: MyType = serde_json::from_str(&serialized).unwrap();
        prop_assert_eq!(value, deserialized);
    }

    #[test]
    fn sort_is_idempotent(mut vec: Vec<i32>) {
        vec.sort();
        let sorted = vec.clone();
        vec.sort();
        prop_assert_eq!(vec, sorted);
    }
}

Async Testing

#[tokio::test]
async fn async_operation_completes_successfully() {
    let result = async_function().await;
    assert!(result.is_ok());
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn concurrent_operations_are_safe() {
    let handles: Vec<_> = (0..10)
        .map(|i| tokio::spawn(async move { process(i).await }))
        .collect();

    for handle in handles {
        handle.await.unwrap();
    }
}

Test Fixtures

struct TestFixture {
    db: TestDatabase,
    client: TestClient,
}

impl TestFixture {
    async fn new() -> Self {
        Self {
            db: TestDatabase::new().await,
            client: TestClient::new(),
        }
    }
}

impl Drop for TestFixture {
    fn drop(&mut self) {
        // Cleanup resources
    }
}

Failure Analysis

When tests fail:

  1. Read the error message - Rust's test output is informative
  2. Check the assertion - Which condition failed?
  3. Examine inputs - What data caused the failure?
  4. Add debug output - Use dbg!() macro temporarily
  5. Isolate the issue - Create minimal reproduction
  6. Fix and verify - Ensure fix doesn't break other tests

Edge Case Requirements

Every function that handles data must have tests for:

Boundary Conditions

#[test]
fn handles_empty_input() {
    assert_eq!(process(&[]), Ok(vec![]));
}

#[test]
fn handles_single_element() {
    assert_eq!(process(&[1]), Ok(vec![1]));
}

#[test]
fn handles_maximum_size() {
    let large = vec![0u8; MAX_SIZE];
    assert!(process(&large).is_ok());
}

#[test]
fn rejects_oversized_input() {
    let too_large = vec![0u8; MAX_SIZE + 1];
    assert!(matches!(process(&too_large), Err(Error::TooLarge(_))));
}

UTF-8 and String Handling

#[test]
fn handles_unicode_correctly() {
    // Multi-byte characters
    assert_eq!(parse("hello"), parse("hello"));

    // Emoji
    assert!(parse("test message").is_ok());

    // RTL text
    assert!(parse("مرحبا").is_ok());

    // Mixed scripts
    assert!(parse("Hello Rust").is_ok());
}

#[test]
fn handles_invalid_utf8() {
    let invalid = &[0xff, 0xfe];
    // Document expected behavior - don't silently ignore!
    assert!(matches!(parse_bytes(invalid), Err(Error::InvalidUtf8)));
}

I/O Error Handling

#[test]
fn handles_missing_file() {
    let result = read_config("/nonexistent/path");
    assert!(matches!(result, Err(Error::NotFound { .. })));
}

#[test]
fn handles_permission_denied() {
    // Create unreadable file in test
    let path = create_unreadable_file();
    let result = read_config(&path);
    assert!(matches!(result, Err(Error::PermissionDenied { .. })));
}

#[test]
fn handles_disk_full() {
    // Mock or use temp filesystem
    let result = write_with_full_disk();
    assert!(matches!(result, Err(Error::DiskFull)));
}

Rule: Never silently ignore I/O or UTF-8 errors. Document the behavior and test it explicitly.

Coverage Guidelines

  • Minimum: 80% line coverage for critical paths
  • Target: 90% for library code
  • Focus: Error handling, edge cases, boundary conditions
  • Required: All error variants must be tested
  • Skip: Generated code, trivial getters/setters

Benchmarking

use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn benchmark_processing(c: &mut Criterion) {
    let data = setup_test_data();

    c.bench_function("process_data", |b| {
        b.iter(|| process(black_box(&data)))
    });
}

criterion_group!(benches, benchmark_processing);
criterion_main!(benches);

Test Naming Convention

{function_name}_{scenario}_{expected_result}

Examples:

  • parse_empty_string_returns_none
  • validate_negative_number_returns_error
  • process_large_input_completes_within_timeout

Testing Unsafe Code

Unsafe code requires extra testing rigor:

/// Module with unsafe code must have:
/// 1. Unit tests for all code paths
/// 2. Property-based tests with proptest
/// 3. Fuzzing targets (optional but recommended)

#[cfg(test)]
mod tests {
    use super::*;
    use proptest::prelude::*;

    // Unit test: specific known inputs
    #[test]
    fn unsafe_operation_valid_input() {
        let data = [1, 2, 3, 4];
        let result = unsafe { unsafe_sum(&data) };
        assert_eq!(result, 10);
    }

    // Property test: random inputs
    proptest! {
        #[test]
        fn unsafe_operation_never_panics(data: Vec<i32>) {
            // This should never panic or cause UB
            let _ = unsafe { unsafe_sum(&data) };
        }

        #[test]
        fn unsafe_matches_safe_impl(data: Vec<i32>) {
            let safe_result = safe_sum(&data);
            let unsafe_result = unsafe { unsafe_sum(&data) };
            prop_assert_eq!(safe_result, unsafe_result);
        }
    }
}

// Fuzz target (in fuzz/fuzz_targets/unsafe_sum.rs)
#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {
    if let Ok(ints) = parse_ints(data) {
        let _ = unsafe { unsafe_sum(&ints) };
    }
});

Advanced Verification Tools

Miri: Undefined Behavior Detection

Miri is an interpreter for Rust's Mid-level Intermediate Representation that detects undefined behavior in unsafe code.

# Install Miri (requires nightly)
rustup +nightly component add miri

# Run all tests under Miri
cargo +nightly miri test

# Run specific test under Miri
cargo +nightly miri test -- test_name

# Run with Stacked Borrows (stricter aliasing checks)
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test

What Miri detects:

  • Use after free, double free
  • Out-of-bounds memory access
  • Invalid use of uninitialized data
  • Violations of aliasing rules (Stacked Borrows)
  • Data races (when using -Zmiri-preemption-rate=0.1)
  • Memory leaks (with -Zmiri-leak-check)

When to run Miri:

  • Every PR that adds or modifies unsafe code
  • As a CI gate for modules containing unsafe
  • Before releasing crates with unsafe internals
// Test that works well with Miri -- avoids I/O and external calls
#[test]
fn miri_compatible_unsafe_test() {
    let mut data = vec![1u8, 2, 3, 4];
    let ptr = data.as_mut_ptr();

    // SAFETY: ptr is valid for data.len() bytes, properly aligned
    unsafe {
        std::ptr::write(ptr.add(2), 42);
    }

    assert_eq!(data[2], 42);
}

Limitations: Miri cannot run code that calls external C functions, performs I/O, or uses inline assembly. Structure tests to isolate pure Rust logic for Miri compatibility.

Fuzzing with cargo-fuzz

# Install cargo-fuzz
cargo install cargo-fuzz

# Initialize fuzzing in your project
cargo fuzz init

# Create a fuzz target
cargo fuzz add parse_input
// fuzz/fuzz_targets/parse_input.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
use my_crate::parse;

fuzz_target!(|data: &[u8]| {
    // Parser should never panic on arbitrary input
    let _ = parse(data);
});

// Structured fuzzing with Arbitrary
use libfuzzer_sys::arbitrary::{self, Arbitrary};

#[derive(Arbitrary, Debug)]
struct FuzzInput {
    query: String,
    limit: u32,
    offset: u32,
}

fuzz_target!(|input: FuzzInput| {
    let _ = search(&input.query, input.limit, input.offset);
});
# Run fuzzer (runs until stopped or crash found)
cargo fuzz run parse_input

# Run for specific duration
cargo fuzz run parse_input -- -max_total_time=300

# Minimize a crashing corpus entry
cargo fuzz tmin parse_input crash-file

# Check coverage of fuzz corpus
cargo fuzz coverage parse_input

Corpus management:

  • Store meaningful seeds in fuzz/corpus/<target>/
  • Commit regression inputs from crashes to the corpus
  • Run cargo fuzz cmin periodically to minimize the corpus

Sanitizers

Sanitizers detect runtime errors that Miri cannot (e.g., in code with FFI or I/O).

# AddressSanitizer: buffer overflows, use-after-free, leaks
RUSTFLAGS="-Zsanitizer=address" cargo +nightly test --target x86_64-unknown-linux-gnu

# ThreadSanitizer: data races in concurrent code
RUSTFLAGS="-Zsanitizer=thread" cargo +nightly test --target x86_64-unknown-linux-gnu

# MemorySanitizer: reads of uninitialized memory
RUSTFLAGS="-Zsanitizer=memory" cargo +nightly test --target x86_64-unknown-linux-gnu

When to use each:

SanitizerDetectsUse When
ASanBuffer overflow, use-after-free, memory leaksAny unsafe code, FFI boundaries
TSanData races, deadlocksConcurrent code with shared state, lock-free structures
MSanReads of uninitialized memoryFFI code receiving data from C, MaybeUninit usage

CI integration: Run sanitizers on a nightly CI job (not blocking, since they require nightly).

Advanced Property Testing with proptest

use proptest::prelude::*;
use proptest::collection::vec;

// Custom strategy for domain-specific types
fn valid_email() -> impl Strategy<Value = String> {
    (
        "[a-z]{1,20}",        // local part
        "[a-z]{1,10}",        // domain
        prop_oneof!["com", "org", "net"],
    )
        .prop_map(|(local, domain, tld)| format!("{}@{}.{}", local, domain, tld))
}

proptest! {
    // Test with custom generators
    #[test]
    fn valid_emails_are_accepted(email in valid_email()) {
        prop_assert!(validate_email(&email).is_ok());
    }

    // Test invariants across transformations
    #[test]
    fn encode_decode_roundtrip(data in vec(any::<u8>(), 0..1024)) {
        let encoded = encode(&data);
        let decoded = decode(&encoded).unwrap();
        prop_assert_eq!(data, decoded);
    }

    // Regression file: proptest stores failing cases in
    // proptest-regressions/ so they're retested on every run
}

Loom: Concurrency Testing

// Use loom for exhaustive concurrency testing of lock-free code
#[cfg(loom)]
use loom::sync::atomic::{AtomicUsize, Ordering};
#[cfg(not(loom))]
use std::sync::atomic::{AtomicUsize, Ordering};

#[cfg(loom)]
#[test]
fn concurrent_counter_is_correct() {
    loom::model(|| {
        let counter = loom::sync::Arc::new(AtomicUsize::new(0));
        let c1 = counter.clone();
        let c2 = counter.clone();

        let t1 = loom::thread::spawn(move || {
            c1.fetch_add(1, Ordering::SeqCst);
        });
        let t2 = loom::thread::spawn(move || {
            c2.fetch_add(1, Ordering::SeqCst);
        });

        t1.join().unwrap();
        t2.join().unwrap();
        assert_eq!(counter.load(Ordering::SeqCst), 2);
    });
}

Disciplined Workflow Integration (Advanced Testing)

  • Research phase (Phase 1): Identify unsafe code paths needing Miri; catalogue parser inputs for fuzz corpus seeding
  • Design phase (Phase 2): Specify which verification tools apply to each module; design fuzz harness API
  • Verification phase (Phase 4): Miri runs on all unsafe code; TSan on all concurrent code; fuzz campaigns on parsers; property tests on invariants
  • Validation phase (Phase 5): Confirm fuzz campaigns have adequate coverage; validate no UB in production-like environment

Cross-references: See rust-development skill for unsafe code policy; see rust-performance skill for concurrency patterns requiring loom/TSan verification.

Constraints

  • Never use real external services in unit tests
  • Never write flaky tests
  • Never test private implementation details
  • Always clean up test resources
  • Keep tests independent - no shared mutable state
  • Add regression tests BEFORE changing code
  • Test all error variants explicitly
  • Document and test I/O and UTF-8 behavior

Success Metrics

  • All tests pass consistently
  • Coverage meets project requirements (80% min, 90% target)
  • No flaky tests in CI
  • Benchmarks show no regressions
  • Test suite completes in reasonable time
  • All error paths tested
  • Edge cases explicitly covered (empty, single, max, overflow)
  • Unsafe code has property tests proving invariants

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.9%
按下载量换算63

Claude

28.46%
按下载量换算52

Cursor

19.13%
按下载量换算35

Gemini CLI

9.55%
按下载量换算17

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

执行命令

安装流程涉及命令执行,可能通过 npx skills add https://github.com/terraphim/terraphim-skills --skill testing 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills