skills/testing/SKILL.md
Comprehensive test writing, execution, and failure analysis. Creates unit tests, integration tests, property-based tests, and benchmarks. Analyzes test failures and improves test coverage.
npx skillsauth add terraphim/codex-skills testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a testing specialist for Rust/WebAssembly projects. You write comprehensive tests, analyze failures, and ensure high code quality through thorough testing strategies.
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."
Unit Testing
Integration Testing
Property-Based Testing
Performance Testing
src/
lib.rs
module.rs
tests/
integration_test.rs # Integration tests
common/
mod.rs # Shared test utilities
benches/
benchmark.rs # Performance benchmarks
#[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(_))));
}
}
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);
}
}
#[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();
}
}
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
}
}
When tests fail:
dbg!() macro temporarilyEvery function that handles data must have tests for:
#[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(_))));
}
#[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)));
}
#[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.
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);
{function_name}_{scenario}_{expected_result}
Examples:
parse_empty_string_returns_nonevalidate_negative_number_returns_errorprocess_large_input_completes_within_timeoutUnsafe 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) };
}
});
development
Xero Accounting API integration skill. Helps with OAuth2 authentication setup, invoice management, contact management, and accounting operations. Provides guidance on rate limits, token refresh, and API best practices.
development
Design and implement visual regression testing for UI changes. Defines screenshot coverage, rendering stabilization, baseline management, and CI integration (e.g., Playwright screenshots, Percy/Chromatic). Use when UI/styling/layout changes need protection against regressions, or when adding screenshot-based tests to a web/WASM/desktop UI.
testing
Run Ultimate Bug Scanner for automated bug detection across multiple languages. Detects 1000+ bug patterns including null pointers, security vulnerabilities, async/await issues, and resource leaks. Integrates with quality-gate workflow.
tools
Knowledge graph-based text replacement using Terraphim hooks. Intercepts commands and text to apply transformations defined in the knowledge graph. Works with Claude Code PreToolUse hooks and Git prepare-commit-msg hooks.