Testing Philosophy
AppFlowy follows a comprehensive testing strategy:Unit Tests
Test individual functions and classes in isolation
Widget Tests
Test Flutter widgets and UI components
Integration Tests
Test complete user flows and features
Rust Tests
Test Rust backend logic and modules
Flutter Testing
Unit Tests
Unit tests verify individual functions and business logic:Widget Tests
Widget tests verify UI components:BLoC Tests
Test state management with BLoCs:Integration Tests
Integration tests verify complete user flows:Running Flutter Tests
1
Run all tests
2
Run specific test file
3
Run tests with coverage
4
Run integration tests
Using cargo-make for Dart Tests
AppFlowy provides convenient cargo-make tasks:Rust Testing
Unit Tests
Rust unit tests are written inline with the code:Async Tests
Test async functions withtokio::test:
Integration Tests
Integration tests are in thetests/ directory:
Running Rust Tests
1
Run all tests
2
Run specific module tests
3
Run tests with output
4
Run single test
Using cargo-make for Rust Tests
Test Backend
AppFlowy provides a test backend for Flutter tests:1
Build test backend
2
Run tests
The test backend is automatically loaded when running Dart tests.
The test backend is built as a dynamic library (cdylib) for easier loading in tests.
Mocking and Test Doubles
Dart Mocking
Usemockito for creating mocks:
Rust Mocking
Use traits for dependency injection:Test Coverage
Flutter Coverage
1
Generate coverage
2
View HTML report
Rust Coverage
1
Install grcov
2
Run tests with coverage
3
View report
CI/CD Testing
AppFlowy runs automated tests on all pull requests:GitHub Actions Workflow
Required Checks
All PRs must pass:- ✅ Dart unit tests
- ✅ Rust unit tests
- ✅ Integration tests
- ✅ Code formatting
- ✅ Linting
Best Practices
Write Tests First
Consider TDD: write tests before implementing features
Test Behavior
Test what the code does, not how it does it
Keep Tests Fast
Fast tests = frequent testing = better quality
Isolate Tests
Each test should be independent and repeatable
Use Descriptive Names
Test names should explain what is being tested
Arrange-Act-Assert
Structure tests clearly: setup, execute, verify
Test Structure
Follow the AAA pattern:Troubleshooting
Flutter Tests Fail
- Clean and retry
- Update dependencies
- Run single test
Rust Tests Fail
- Clean and retry
- Update dependencies
- Run with backtrace
Next Steps
Contributing
Contribute your changes with tests
Code Style
Follow coding conventions
Building
Build AppFlowy from source
Architecture
Understand the architecture