Cyfrin

Testing Your Detector

Write tests for custom detectors

Testing Your Detector

Write tests to ensure your detector works correctly.

Test Structure

Aderyn uses Rust's built-in testing framework.

Example Test

#[cfg(test)]
mod tests {
    use super::*;
    use crate::context::workspace_context::WorkspaceContext;
    
    #[test]
    fn test_useless_modifier_detector() {
        // Load test contracts
        let context = WorkspaceContext::from_path(
            "tests/contract-playground"
        );
        
        // Run detector
        let detector = UselessModifierDetector;
        let findings = detector.detect(&context);
        
        // Assert findings
        assert!(!findings.is_empty());
        assert_eq!(findings.len(), 2);
        assert!(findings[0].title.contains("Useless"));
    }
}

Test Contracts

Use contracts from tests/contract-playground:

// tests/contract-playground/UselessModifier.sol
contract TestContract {
    modifier uselessModifier() {
        // Empty - should be detected!
    }
    
    function someFunction() public uselessModifier {
        // ...
    }
}

Running Tests

cargo test

Run specific test:

cargo test test_useless_modifier_detector

Test Playground

Clone aderyn-contracts-playground for more test contracts.

Best Practices

  1. Test positive cases - Contracts that should trigger detector
  2. Test negative cases - Contracts that shouldn't trigger
  3. Test edge cases - Unusual code patterns
  4. Multiple findings - Ensure all instances are caught

Example: Complete Test

#[test]
fn test_reentrancy_detector() {
    let context = WorkspaceContext::from_path("tests/contracts");
    let detector = ReentrancyDetector;
    let findings = detector.detect(&context);
    
    // Should find reentrancy in VulnerableContract
    assert!(!findings.is_empty());
    
    // Should NOT find reentrancy in SafeContract  
    let safe_findings: Vec<_> = findings.iter()
        .filter(|f| f.contract_name.contains("Safe"))
        .collect();
    assert!(safe_findings.is_empty());
}

Next Steps

Detector Patterns

Learn useful AST traversal patterns