Testing Dart packages with GitHub Actions

Ryan Edge
Flutter Community
Published in
6 min readJun 2, 2020

Originally published at https://chimon.hashnode.dev.

If you are viewing this article on a mobile device, you may have a better viewing experience with the original article linked below. Medium’s code snippets leave much to be desired.

The Problem

As the author of a several Flutter applications & Dart packages, I have spent entirely too much of my life scouring the internet and piecing together tutorials for CI/CD workflows for Flutter applications & Dart packages, so I decided to publish my own. The following article is meant to demonstrate a simple workflow for a Flutter/Dart package using GitHub Actions, my preferred platform for CI/CD. You can see a fully working example of the workflow here.

Create a Code Coverage account

To publish code coverage results, you will want to create a code coverage account. You can simplify the process by authenticating with GitHub. This example uses codecov.io but coveralls should have a similar process.

1. Add a new repository

From the Repositories tab, select “Add a new repository”.

Add a repository
Add a repository

2. Find your repository

You will be taken to a page that allows you to search for the repository that you want to add coverage support to. Find your repository and select it.

Choose a new repository
Choose a new repository

3. Save your upload token

On the next screen, you’ll be presented with an Upload token. Save this — it will be added as a secret to your project to upload code coverage results.

Configure Code Coverage

Next you’ll need to set up the GitHub integration with Code Coverage. The easiest way to do this is to select the GitHub Integration action from the Account settings page.

Select GitHub Integration action
Select GitHub integration option

From there you’ll be redirected to add the integration in GitHub. You can set up code coverage to be configured for all repositories or only select. I set mine up for specific repositories. We’ll also want to add that code coverage token from the previous step as a new secret. Call the secret CODECOV_TOKEN.

Create project secret
Create project secret

Setting up the GitHub Action

We could create a GitHub Action from our IDE of choice or directly from GitHub. For the sake of brevity, let’s use GitHub.

1. Create an action

Create GitHub action
Create GitHub action

From the Actions tab of your GitHub repository, select “set up a workflow yourself”. You could use the Dart workflow to get a simple workflow set up for you, but this workflow will only work if you do not need Flutter as a dependency. You can see an example that just uses the Dart workflow here.

2. Name the workflow.

name: Test

You can name the workflow whatever you want. Because this workflow is only testing the package, I’ve given it the name test.

3. Define workflow triggers.

on: 
push:
branches: [ master ]
pull_request:
branches: [ master ]

Triggers determine when a GitHub Action runs. You can learn more about them here. For our workflow, we probably want to run tests for each pull request to know whether something broke before we merge. We also want to run tests on pushes directly to master in case an administrator accidentally (or intentionally in my case) pushes a bad commit without going through the PR process.

4. Create the job to test

Now it’s time to define the meat of our workflow file. Let’s examine each step individually.

a. Specify the running platform

jobs: 
test:
runs-on: macos-latest
steps:

You can specify any number of platforms to run your jobs on. In this case we use macOS, but this is only really necessary if you’re building iOS/macOS apps. From here, we will define the steps that will be ran as part of the workflow. Think of each step as a command to be executed.

b. Add step to checkout project

- uses: actions/checkout@v1

The first step is to check out the project so that we may run additional commands against it.

c. Add step to setup Flutter

- name: Install Flutter 
uses: subosito/flutter-action@v1.3.2

Next, we install Flutter so that we may execute Flutter commands in later steps.

d. Add step to install dependencies

- name: Install dependencies 
run: flutter pub get

Next, we install the project dependencies.

e. Add step to run tests with coverage

- name: Test app 
run: flutter test --coverage

This workflow would be nothing without our command to run our tests, so let’s add that. Notice that to generate coverage when running tests, we need to use the --coverage flag. By default the code coverage will be output to coverage/lcov.info.

f. Add step to publish coverage results

- name: Upload coverage to Codecov 
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: coverage/lcov.info

Finally, we publish our code coverage results using the previously defined token. The token is made available as an environment variable on the secrets object. We also need to specify the location of our code coverage results.

NOTE: Adding the token is optional, it is automatically grabbed by the codecov action, but for the sake of this article I am being explicit.

Complete workflow file

We have finished building our workflow file. It should closely resemble the following:

name: Teston:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: Install Flutter
uses: subosito/flutter-action@v1.3.2
- name: Install app dependencies
run: flutter pub get
- name: Test app
run: flutter test --coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: coverage/lcov.info

This step allows us to publish our code coverage results using the previously defined token. The token is made available as an environment variable on the secrets object. We also need to specify the location of our code coverage results.

5. Commit your changes, have a tea break

All that’s left is to commit these changes and we’re done! You should immediately be able to see your action running.

GitHub Action results
GitHub Action results

Conclusion

Hopefully you now have a better understanding of how GitHub Actions work and how to can set up a simple workflow for your Flutter application or package without involving any pesky 3rd party services. Happy trails on your DevOps journey. 😊😊😊

Sup?! I’m Ryan Edge. I am a Software Engineer at Superformula and a semi-pro open source contributor. If you liked this article, be sure to follow and spread the love! Happy trails

--

--

Ryan Edge
Flutter Community

I know everything there is to know about computers. All the Twitters — I know `em.