Unit Tests and Coverage Reports in Multi-package Flutter Project
--
When developing a side project, or relatively small project, it is common to use a single flutter package where all the code resides. To improve it further, the code can be separated into multiple folders such as data, domain, presentation layers, and even feature folders.
However, for more complex projects, this monolith architecture may not be scalable. The developer team might grow and, in the end, different teams own specific part of the applications, like “core package”, “design package” and etc. Even further, some packages might be moved to another repository.
In this article, I will not discuss the pros and cons of both approaches, instead, I will mainly focus on the unit tests and code coverage part for the multi-package projects. To handle multi-package architecture, and to execute the flutter commands like flutter test
, flutter analyze
in every package, we are using a third party library, Melos. You can ask yourself, do we really need another library to manage multiple packages? The answer would be: No, you can create and maintain your own scripts and run them for every packages or for specific packages. However, Melos will make your life easier with its powerful functionality. You can check what you can do with Melos here.
How to use Melos?
Melos can be installed as a global package via pub.dev. Copy the following command to your terminal to install Melos.
dart pub global activate melos
Melos requires a few one-off steps to be completed before it can be used. To set up the project to use Melos, create a melos.yaml
file in the root of the project.
Within the melos.yaml
file, add name
and packages
fields:
name: <PROJECT_NAME>
packages:
- core/**
- core_features/**
- '*'
Once installed & setup, Melos needs to be bootstrapped. Bootstrapping has 2 primary roles:
- Installing all package dependencies (internally using
pub get
). - Locally linking any packages together.
melos bootstrap
Unit tests scripts, coverage scripts and more…
At this point, we have already installed and setup the melos. So we can dive into the script part. We can use existing command like flutter analyze
or create our own scripts and run these scripts in every package with the help of melos exec
command. Here is a few example of scripts that we use in our project:
analyze
script run flutter analyze
in every package with the help of melos exec
.
unit-test
script runs the flutter test --no-pub --coverage
in every package that contains “test” folder with the help of melos exec
. Since we add --fail-fast
argument to the melos exec
command, the script will complete if any of the tests cases fail.
unit_test_and_coverage
script removes the generated coverage folder first, then run the unit-test
script. After this step, a coverage folder will be generated for every package that has test folder in it. Then melos will execute coverage filter --input ./coverage/lcov.info --output MELOS_ROOT_PATH/coverage/filtered.lcov.info --filters \.g\.dart
command for every package that has coverage/lcov.info
file. At the end, all the coverage reports excluding the filtered files \.g\.dart
will be merged under the <project_root>/coverage/filtered.lcov.info
file. As the next step coverde
toolv will check the coverage file and write the result to <project_root>/coverage/result.txt
file.
This file shows the individual code coverage percentage for every file, and also at the end, it shows the overall code coverage of the project. The output of the command is written to this file because, later, we can parse this file in CI/CD platforms, and have a code coverage check in Pull Requests 😉. If you don’t want to do this, you can also ignore > MELOS_ROOT_PATH/coverage/result.txt
part.
To run the unit_test_and_coverage
script, coverde cli tool needs to be installed:
dart pub global activate coverde
How to visualise the generated coverage report?
When we rununit_test_and_coverage
with melos, a filtered and merged coverage report file is generated, but, this file format is not user friendly. When we open the file we see something like this:
To generate an html report out of that, we have to do the following:
# install the lcov tool to convert the lcov.info file to html files.brew install lcov# generate html file by giving the input and output pathsgenhtml coverage/filtered.lcov.info -o coverage/html
After running the above commands, when we open the main index file, we can see an informative, nicely formatted html reports. From there, we can navigate through files and see the coverages line by line.
What is next?
I hope you find the article informative and enjoy while reading ☺️. As the next step, I will explain how we can use CI/CD platforms to generate this code coverage report and use it in the PR checks. I will also explain how to generate a fancy coverage badge and display it in our repository.
Feel free to comment, and ask for more information if needed. You can also connect with me on LinkedIn ☺️.