How to upload coverage to CodeCov for Dart and Flutter
Tagged under: dartfluttertestingcode_coverage
Code Coverage helps you identify how much of your code is covered via test cases. Coverage itself is an interesting idea. People are largely divided on it but coverage can be a useful metric if used for objective information and not used to measure success. In this post, we'll cover generating coverage for flutter and dart (each individually), formatting that coverage if needed, and then uploading it to CodeCov via Github actions.
I understand where you're coming from. Code coverage should be an informative metric, not a success metric.— Brad Cypert (@bradcypert) May 18, 2022
Dart and Flutter both ship with testing tools that are capable of producing coverage reports. Flutter generates a nice
.lcov file for you and Dart... does not ☹️. If you're unaware, LCOV is the graphical frontend to GCOV, which is GCC's coverage testing tool. A lot of work has gone into LCOV so being able to leverage that file spec can be really beneficial. In Flutter, to get an lcov report, all we have to do is run
flutter test --coverage and that will generate a file at
./coverage/lcov.info. If you'd like to display that in the browser, you can use the
genhtml command from
genhtml coverage/lcov.info -o coverage/html.
Dart, however, does not give us a nice lcov coverage file. To generate our coverage files, we can run
dart run test --coverage="coverage". This will generate a
coverage folder with
.json files for our coverage report. These, unfortunately, aren't lcov files (which CodeCov wants), but thankfully there's a tool we can use to format our coverage as an lcov file. You can run
dart pub global activate coverage to add the coverage binaries to your pub_cache path. Running
$HOME/.pub-cache/bin/format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.packages --report-on=lib will convert your Dart coverage files to a single lcov file.
pubcache and the pathWhen you install coverage, you may see something like:
Warning: Pub installs executables into $HOME/.pub-cache/bin, which is not on your path.You can fix that by adding this to your shell's config file (.bashrc, .bash_profile, etc.):export PATH="$PATH":"$HOME/.pub-cache/bin"
Following the above instructions can help you turn
format_coverage, which is nice but our github actions container has a small issue with the pub cache not being on the path, so we'll reference it directly through the rest of this post.
Now that we have a path to standardize our Dart and Flutter coverage reports around lcov, we can shove all of this into a github actions workflow and get things uploading. To do this, we'll use the CodeCov action (codecov/codecov-action@v2). Creating our Github workflow should be relatively easy now that we've gone through the steps up to this point. You can define whatever
on hooks that suit your needs, but the important part for now is the
name: Dart CIon:push:branches: [ main ]pull_request:branches: [ main ]jobs:build:runs-on: ubuntu-latestcontainer:image: dart:lateststeps:- uses: actions/checkout@v2- name: Install dependenciesrun: dart pub get- name: Run testsrun: dart pub run test --coverage="coverage"- name: Install coverage toolsrun: dart pub global activate coverage- name: format coveragerun: $HOME/.pub-cache/bin/format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.packages --report-on=lib- uses: codecov/codecov-action@v2with:files: coverage.lcovverbose: true # optional (default = false)
This action will run your tests and generate a coverage report, then upload that to CodeCov. If you're using Flutter, you can swap out the
Run tests step and remove the
Install coverage tools and
format coverage steps -- It's a lot simpler with just Flutter!
Just a heads up, Codecov works really easily with public repos, but there are a few more steps required to set up a private repo. The steps required (its mostly just generating and setting a token) can be found here: https://github.com/codecov/codecov-action#usage.