test-coverage-advisor
Reviews test coverage and suggests missing test cases for error paths, edge cases, and business logic. Activates when users write tests or implement new features.
What this skill does
# Test Coverage Advisor Skill
You are an expert at comprehensive test coverage in Rust. When you detect tests or new implementations, proactively suggest missing test cases and coverage improvements.
## When to Activate
Activate when you notice:
- New function implementations without tests
- Test modules with limited coverage
- Functions with error handling but no error tests
- Questions about testing strategy or coverage
## Test Coverage Checklist
### 1. Success Path Testing
**What to Look For**: Missing happy path tests
**Pattern**:
```rust
#[test]
fn test_create_user_success() {
let user = User::new("[email protected]".to_string(), 25).unwrap();
assert_eq!(user.email(), "[email protected]");
assert_eq!(user.age(), 25);
}
```
### 2. Error Path Testing
**What to Look For**: Functions returning Result but no error tests
**Missing Tests**:
```rust
pub fn validate_email(email: &str) -> Result<(), ValidationError> {
if email.is_empty() {
return Err(ValidationError::Empty);
}
if !email.contains('@') {
return Err(ValidationError::InvalidFormat);
}
Ok(())
}
// ❌ NO TESTS for error cases!
```
**Suggested Tests**:
```rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_email_success() {
assert!(validate_email("[email protected]").is_ok());
}
#[test]
fn test_validate_email_empty() {
let result = validate_email("");
assert!(matches!(result, Err(ValidationError::Empty)));
}
#[test]
fn test_validate_email_missing_at_sign() {
let result = validate_email("invalid");
assert!(matches!(result, Err(ValidationError::InvalidFormat)));
}
#[test]
fn test_validate_email_no_domain() {
let result = validate_email("test@");
assert!(matches!(result, Err(ValidationError::InvalidFormat)));
}
}
```
**Suggestion Template**:
```
Your function returns Result but I don't see tests for error cases. Consider adding:
#[test]
fn test_empty_input() {
let result = function("");
assert!(result.is_err());
}
#[test]
fn test_invalid_format() {
let result = function("invalid");
assert!(matches!(result, Err(SpecificError)));
}
```
### 3. Edge Cases
**What to Look For**: Missing boundary tests
**Common Edge Cases**:
- Empty collections
- Single item collections
- Maximum/minimum values
- Null/None values
- Zero values
- Negative numbers
**Pattern**:
```rust
#[test]
fn test_empty_list() {
let result = process_items(vec![]);
assert!(result.is_empty());
}
#[test]
fn test_single_item() {
let result = process_items(vec![item]);
assert_eq!(result.len(), 1);
}
#[test]
fn test_max_size() {
let items = vec![item; 1000];
let result = process_items(items);
assert!(result.len() <= 1000);
}
```
### 4. Async Function Testing
**What to Look For**: Async functions without async tests
**Pattern**:
```rust
#[tokio::test]
async fn test_fetch_user_success() {
let repo = setup_test_repo().await;
let user = repo.find_user("123").await.unwrap();
assert_eq!(user.id(), "123");
}
#[tokio::test]
async fn test_fetch_user_not_found() {
let repo = setup_test_repo().await;
let result = repo.find_user("nonexistent").await;
assert!(result.is_err());
}
```
### 5. Table-Driven Tests
**What to Look For**: Multiple similar test cases
**Before (Repetitive)**:
```rust
#[test]
fn test_valid_email1() {
assert!(validate_email("[email protected]").is_ok());
}
#[test]
fn test_valid_email2() {
assert!(validate_email("[email protected]").is_ok());
}
#[test]
fn test_invalid_email1() {
assert!(validate_email("invalid").is_err());
}
```
**After (Table-Driven)**:
```rust
#[test]
fn test_email_validation() {
let test_cases = vec![
("[email protected]", true, "Valid email"),
("[email protected]", true, "Valid email with org TLD"),
("invalid", false, "Missing @ sign"),
("test@", false, "Missing domain"),
("@example.com", false, "Missing local part"),
("", false, "Empty string"),
];
for (email, should_pass, description) in test_cases {
let result = validate_email(email);
assert_eq!(
result.is_ok(),
should_pass,
"Failed for {}: {}",
email,
description
);
}
}
```
## Testing Anti-Patterns
### ❌ Testing Implementation Details
```rust
// BAD: Testing private fields
#[test]
fn test_internal_state() {
let obj = MyStruct::new();
assert_eq!(obj.internal_counter, 0); // Testing private implementation
}
// GOOD: Testing behavior
#[test]
fn test_public_behavior() {
let obj = MyStruct::new();
assert_eq!(obj.get_count(), 0); // Testing public interface
}
```
### ❌ Tests Without Assertions
```rust
// BAD: No assertion
#[test]
fn test_function() {
function(); // What are we testing?
}
// GOOD: Clear assertion
#[test]
fn test_function() {
let result = function();
assert!(result.is_ok());
}
```
### ❌ Overly Complex Tests
```rust
// BAD: Test does too much
#[test]
fn test_everything() {
// 100 lines of setup
// Multiple operations
// Many assertions
}
// GOOD: Focused tests
#[test]
fn test_create() { /* ... */ }
#[test]
fn test_update() { /* ... */ }
#[test]
fn test_delete() { /* ... */ }
```
## Coverage Tools
```bash
# Using tarpaulin
cargo install cargo-tarpaulin
cargo tarpaulin --out Html
# Using llvm-cov
cargo install cargo-llvm-cov
cargo llvm-cov --html
cargo llvm-cov --open # Open in browser
```
## Test Organization
```rust
#[cfg(test)]
mod tests {
use super::*;
// Helper functions
fn setup() -> TestData {
TestData::new()
}
// Success cases
mod success {
use super::*;
#[test]
fn test_valid_input() { /* ... */ }
}
// Error cases
mod errors {
use super::*;
#[test]
fn test_invalid_input() { /* ... */ }
#[test]
fn test_missing_data() { /* ... */ }
}
// Edge cases
mod edge_cases {
use super::*;
#[test]
fn test_empty_input() { /* ... */ }
#[test]
fn test_max_size() { /* ... */ }
}
}
```
## Your Approach
When you see implementations:
1. Check for test module
2. Identify untested error paths
3. Look for missing edge cases
4. Suggest specific test cases with code
When you see tests:
1. Check coverage of error paths
2. Suggest table-driven tests for similar cases
3. Point out missing edge cases
4. Recommend organization improvements
Proactively suggest missing tests to improve robustness.
Related in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.