Unit Tests and Coverage Reports in Multi-package Flutter Project

Meliksah Cakir
4 min readNov 1, 2022

--

Photo by Clay Banks on Unsplash

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:

  1. Installing all package dependencies (internally using pub get).
  2. 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:

complete melos.yaml file

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:

A portion of the generated lcov.info file

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.

Coverage report for the overall project
Line coverage for the specific file

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 ☺️.

--

--