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
- Test positive cases - Contracts that should trigger detector
- Test negative cases - Contracts that shouldn't trigger
- Test edge cases - Unusual code patterns
- 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