Running Tests
Rust’s testing framework is built intocargo:
Run All Tests
- Unit tests (in
#[cfg(test)]modules) - Integration tests (in
tests/directory) - Documentation tests (in doc comments)
Run Specific Tests
Test a specific module:Show Test Output
By default, Rust captures stdout/stderr. To see print statements:Writing Tests
Unit Tests
Unit tests live in the same file as the code being tested, in a#[cfg(test)] module:
src/commands/ping.rs
src/commands/ping.rs:50-78 for the complete implementation.
Test Patterns
Annie Mei follows a testable architecture pattern:- Core logic - Transport-agnostic, pure functions
- Adapter - Thin wrapper that calls Serenity APIs
src/commands/ping.rs:
handle_ping() without mocking Discord APIs.
Integration Tests
Integration tests go in thetests/ directory:
tests/integration_test.rs
Mocking External APIs
For commands that call external APIs (AniList, MAL, Spotify), mock the responses:src/commands/anime/command.rs:136-209 for complete examples.
Code Quality Tools
Formatting with rustfmt
Format all code according to Rust style guidelines:Linting with Clippy
Run the Clippy linter to catch common mistakes:Type Checking
Fast type checking without building:cargo build and catches most errors.
Code Coverage
Generate code coverage reports usingcargo-tarpaulin:
Install tarpaulin
Generate Coverage Report
tarpaulin-report.html.
For CI/CD, output in XML format:
Benchmarking
Benchmark performance-critical code:benches/fuzzy_bench.rs
Pre-Commit Workflow
Before committing, run this checklist:1
Format Code
2
Run Linter
3
Run Tests
4
Check Types
CI/CD Testing
Annie Mei uses GitHub Actions for automated testing. The workflow:- Run
cargo fmt -- --check - Run
cargo clippy -- -D warnings - Run
cargo test - Build release binary
.github/workflows/ for workflow definitions.
Test-Driven Development
Follow TDD for new features:1
Write a Failing Test
Start with a test that captures the desired behavior:
2
Run the Test
Verify it fails:
3
Implement the Feature
Write minimal code to make the test pass:
4
Run the Test Again
Verify it passes:
5
Refactor
Improve the implementation while keeping tests green:
Debugging Tests
Print Debugging
Useprintln! or dbg! in tests:
Test-Specific Logging
Enable logging in tests:Running Single Tests in Debug Mode
Best Practices
Test Naming
Use descriptive test names:Format:
function_scenario_expectedBehaviorArrange-Act-Assert
Structure tests clearly:
Test Independence
Each test should be independent:
- Don’t rely on test execution order
- Clean up resources after tests
- Avoid shared mutable state
Edge Cases
Test boundary conditions:
- Empty strings
- Null values (None)
- Maximum/minimum values
- Invalid input
Next Steps
Adding Commands
Learn how to write testable command handlers
Architecture
Understand testable design patterns
Rust Testing Book
Official Rust testing documentation
