- Very few tests:
modules/common/test/core/result_type_test.dartandmodules/domain/test/env/env_config_test.dart.appanddatahave notest/directory. - There are no integration tests (
integration_test/), no golden tests, and no mocks or fakes checked in. - The test dependencies are declared but unused:
app:flutter_test,bloc_test,mocktail,build_runnerdomain,data:flutter_test,mocktailtool/project_init(pure Dart):test. Its suite initializes a temporary copy of the repositorycommon:flutter_testonly
- There's no coverage threshold. Coverage is collected and uploaded to SonarQube by
coverage/full_coverage.py. - CI (
.github/workflows/ci.yml) runsmelos run verify(format, analyze, test) on every PR.
| What | Command |
|---|---|
| All packages (what CI runs) | melos run test (from the repo root; flutter test in Flutter packages, dart test in pure-Dart ones) |
| One package | cd <pkg> && flutter test (dart test in tool/project_init) |
| One file | flutter test test/path/to/file_test.dart (from the package dir) |
| Coverage for one package | flutter test --coverage → <pkg>/coverage/lcov.info |
| Merged coverage + Sonar | python3 coverage/full_coverage.py (interactive), --ci, or --dry-run |
Use fvm flutter if flutter isn't aliased to the pinned SDK. A package's tests only run once it has a test/
directory: melos run test and full_coverage.py (which iterates the packages listed in
sonar.sources) both skip packages without one.
These follow from the declared dev dependencies and the architecture. Keep new suites consistent with them.
- Location: mirror
lib/under the owning package'stest/, for examplemodules/domain/test/bloc/auth/auth_cubit_test.dartformodules/domain/lib/bloc/auth/auth_cubit.dart. File suffix_test.dart. - Cubits (domain): use
bloc_test'sblocTestwith amocktailmock of the service. Assert theResourcesequence (RLoading→RSuccess/RError).bloc_testis currently only anappdev dependency, so add it tomodules/domain/pubspec.yamldev_dependencies(thenmelos bootstrap) when you write the first domain cubit test. - Services: plain
testwith a mocked repository interface. - Repositories (data): mock
Dio/Preferenceswithmocktail. Cover DTO → model mapping andDioException→Failurefor each error type you handle. - Common utilities: pure unit tests (
FormValidator,ResultType,FailureMapper,Resource). These are the cheapest high-value tests in the repo. - Widgets (app):
testWidgets, providing cubits withBlocProvider.valueover aMockCubit(frombloc_test). Localized widgets needlocalizationsDelegates: LangExtensions.appLocalizationDelegateson the testMaterialApp. Anything that readsgetItneeds registrations insetUp. CallGetIt.instance.reset()intearDown. - Mocks: use
mocktail(no codegen). It's the only mocking library declared. Don't addmockito, which needs build_runner and produces generated*.mocks.dartfiles. - When you add a package's first tests, add
<pkg>/testtosonar.testsinsonar-project.properties. It currently listsmodules/common/testandmodules/domain/test, which are the directories that exist. - Changing a template file the initializer edits? Run
cd tool/project_init && dart test; it fails on drift. - Added or upgraded a dependency? The same tests fail if it brings in a package missing from
tool/project_init/lib/src/resolved_packages.dart; add the names they report.
| Change | Minimum tests |
|---|---|
| New/changed cubit | blocTest for each public method: success and error paths |
| New/changed repository impl | mapping + each failure path |
| New/changed common utility | unit tests covering its branches |
| New page / significant widget | widget test for the loading, error, and success renderings |
| Bug fix | a regression test that fails without the fix |