Scaffolding Tests ๐งช
One of the most interesting and time-saving elements of scaffolding is generating the unit tests to achive 100% coverage. This provide a great set of boiler plate examples to borrow from as you evolve your application away from the initial scaffold.
scaffolding_test is a option mason brick that is called when the option --generate-tests
is true.
To allow these unit test to work with our flutter project we have 2 exra dependencies - bloc_test
and mocktail
. Add those to the project as follows:
flutter pub add mocktail bloc_test --dev
To continue with the previous example, lets add unit tests and use the command parameters to do this.
mason make scaffolding --package static_scaffolding_sample --feature feature1 \
--properties "String firstname=Your first name, String lastname=Your suranme, bool registered=false" \
--generate-tests true --generate-home true
Running this you will see a similar output to the following:
You have the following properties: [{name: firstname, type: String, defaultValue: 'Your first name', emptyValue: '', testValue: 'testString'}, {name: lastname, type: String, defaultValue: 'Your suranme', emptyValue: '', testValue: 'testString'}, {name: registered, type: bool, defaultValue: false, emptyValue: false, testValue: true}]
โ Made brick scaffolding (0.1s)
โ Generated 15 file(s):
.../static_scaffolding_sample/lib/features/feature1/feature1.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/data/feature1_repository_impl.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/data/feature1_model.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/domain/feature1_repository.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/domain/feature1.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/views/feature1_edit_view.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/views/feature1_read_view.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/widgets/feature1_widget.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_edit_event.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_edit_bloc.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_edit_state.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_read_event.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_read_bloc.dart (identical)
.../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_read_state.dart (identical)
.../static_scaffolding_sample/lib/shared/presentation/list_table.dart (identical)
โ Compiled post_gen.dart (2.4s)
โ Running brick scaffolding_home (0.7s)
โ Generated 2 file(s):
.../static_scaffolding_sample/lib/main.dart (identical)
.../static_scaffolding_sample/lib/scaffold_app.dart (identical)
โ Running brick scaffolding_test (0.7s)
โ Generated 8 file(s):
.../static_scaffolding_sample/test/features/feature1/data/feature1_repository_impl_test.dart (new)
.../static_scaffolding_sample/test/features/feature1/data/feature1_model_test.dart (new)
.../static_scaffolding_sample/test/features/feature1/domain/feature1_test.dart (new)
.../static_scaffolding_sample/test/features/feature1/presentation/views/feature1_read_view_test.dart (new)
.../static_scaffolding_sample/test/features/feature1/presentation/views/feature1_edit_view_test.dart (new)
.../static_scaffolding_sample/test/features/feature1/presentation/widgets/feature1_widget_test.dart (new)
.../static_scaffolding_sample/test/features/feature1/presentation/bloc/feature1_read_bloc_test.dart (new)
.../static_scaffolding_sample/test/features/feature1/presentation/bloc/feature1_edit_bloc_test.dart (new)
โ Running brick scaffolding_home_test (0.6s)
โ Generated 1 file:
.../static_scaffolding_sample/test/scaffold_app_test.dart (new)
Note the new files now created under test/
. Given we also specified to generate the home scaffold we also go the unit test for this.
The full list of addtional files are:
test/
โโ scaffold_app_test.dart
โโ features/
โโ feature1/
โโ data/
โ โโ feature1_model_test.dart
โ โโ feature1_repository_impl_test.dart
โโ domain/
โ โโ feature1_test.dart
โโ presentation/
โโ bloc/
โ โโ feature1_edit_bloc_test.dart
โ โโ feature1_read_bloc_test.dart
โโ views/
โโ feature1_edit_view_test.dart
โโ feature1_read_view_test.dart
To show our tests in action we can run them and generate the coverage report as follows:
flutter test --coverage && genhtml -p ./lib -o coverage coverage/lcov.info && open coverage/index.html
lcov
On mac this is as simple as brew install lcov
if you have install homebrew
The result of running this command is
00:10 +62: All tests passed!
Reading data file coverage/lcov.info
Resolved relative source file path "lib/features/feature1/data/feature1_model.dart" with CWD to "/Users/shorn/dev/static_scaffolding_sample/lib/features/feature1/data/feature1_model.dart".
Found 15 entries.
Using user-specified filename prefix "./lib"
Writing .css and .png files.
Generating output.
Processing file .../static_scaffolding_sample/lib/scaffold_app.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/data/feature1_model.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/data/feature1_repository_impl.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/domain/feature1.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/domain/feature1_repository.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_read_event.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_read_bloc.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_read_state.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_edit_event.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_edit_state.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/bloc/feature1_edit_bloc.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/views/feature1_read_view.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/views/feature1_edit_view.dart
Processing file .../static_scaffolding_sample/lib/features/feature1/presentation/widgets/feature1_widget.dart
Processing file .../static_scaffolding_sample/lib/shared/presentation/list_table.dart
Writing directory view page.
Overall coverage rate:
lines......: 100.0% (394 of 394 lines)
functions..: no data found
and the following will show in a browser window
Congratulations ๐ฅณ 421 lines and 100% coverage. You can edit these files to learn more about how they are unit tested and as you change the scaffold you are in a good place to consider Test Driven Development (TDD) with some great examples.