Testing Strategy & Guidelines
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The testing strategy for the BT Speaker project is designed to ensure the reliability of a Flutter-embedded monorepo consisting of a Raspberry Pi display application (pi_app), a phone companion application (phone_app), and a shared core logic package (bt_speaker_core). Given the hardware-dependent nature of the project (Raspberry Pi Zero 2 W and WS2812B LEDs), the strategy emphasizes a combination of unit testing for business logic, widget testing for UI components, and specialized integration testing for WebSocket communication.
The project utilizes Melos to orchestrate testing across the monorepo, ensuring that all packages are validated through automated CI/CD pipelines. Testing focus is divided between the shared data models, the BLoC state management layers, and the communication protocols between the phone and the Pi.
Sources: CLAUDE.md:3-9, README.md:17-23, melos.yaml:14-20
Testing Frameworks and Tooling
The project relies on standard Flutter and Dart testing libraries, supplemented by specialized tools for state management and monorepo management.
Primary Testing Stack
| Tool | Purpose | Source |
|---|---|---|
flutter_test | Base testing framework for unit and widget tests. | apps/pi_app/pubspec.yaml:57 |
bloc_test | Specialized testing for BLoC state changes and events. | apps/pi_app/pubspec.yaml:56 |
mocktail | Mocking library for dependency injection in tests. | apps/phone_app/pubspec.yaml:60 |
melos | Monorepo management for running tests across all packages. | pubspec.yaml:14 |
very_good_analysis | Linter for enforcing code quality and documentation. | packages/bt_speaker_core/pubspec.yaml:23 |
Sources: apps/pi_app/pubspec.yaml:56-59, apps/phone_app/pubspec.yaml:59-62, melos.yaml:14-20
Testing Layers
Unit and BLoC Testing
The project follows a "BLoC-per-feature" pattern. Tests utilize the bloc_test package to verify that specific events trigger the correct states. The pattern involves MockBloc, whenListen, and isA<>() to validate state transitions.
Sources: CLAUDE.md:52-54
Widget Testing
Widget tests focus on the UI components in both the Pi and phone applications. These tests use MockBloc to simulate state and are wrapped in BlocProvider<T>.value to provide the necessary dependencies to the widget tree.
Sources: CLAUDE.md:55
Integration Testing (WebSocket)
Integration tests specifically target the communication between the phone and the Pi. These tests utilize a WebSocketServer instance bound to port 0 (allowing the OS to assign an available port).
Critical Coordination: Because the WebSocket server start-up and communication are asynchronous, tests require Future.delayed coordination to prevent hangs and ensure the server is ready before the client attempts to connect.
Sources: CLAUDE.md:52-57
The diagram shows the coordination required for WebSocket integration tests to avoid hangs. Sources: CLAUDE.md:55-57
Monorepo Test Execution
Melos is used to automate test execution across the workspace. The configuration allows for running tests on all packages or only on those with changes.
Melos Test Commands
| Command | Action | Scope |
|---|---|---|
melos run test | flutter test --coverage | Changed packages with a test/ directory. |
melos run test:all | flutter test --coverage | All packages with a test/ directory. |
Sources: melos.yaml:14-20, melos.yaml:31-37
CI/CD Integration
GitHub Actions are configured to run the test suite across a matrix of the three main packages. A specific guard (if [ -d "test" ]) is implemented to skip packages that do not yet contain a test directory, such as the initial state of the phone_app.
Sources: CLAUDE.md:60-62
Guidelines and Conventions
To maintain consistency and avoid common pitfalls during testing, the following guidelines must be followed:
- Naming Hazards: When importing material components in tests, always hide the default
ConnectionStateto avoid conflicts with custom models:import 'package:flutter/material.dart' hide ConnectionState; - Async Coordination: Never await
server.start()directly in a way that blocks the test execution; use unawaited starts with timed delays for coordination. - Randomized Ordering: Tests are run with
--test-randomize-ordering-seed=randomto ensure no hidden dependencies exist between individual test cases. - Coverage: All test runs should include the
--coverageflag to support reporting via Codecov.
Sources: CLAUDE.md:41-47, CLAUDE.md:56-57, melos.yaml:18, README.md:53
Conclusion
The testing strategy for BT Speaker prioritizes the decoupled validation of the shared core and the independent BLoC layers of each application. By leveraging Melos and automated CI guards, the project ensures that hardware-specific constraints (like those of the Pi Zero 2 W) do not compromise the software's stability during the development of complex features like real-time audio visualization and WebSocket-based control.
Sources: CLAUDE.md:60-62, README.md:46-53