Engineering

CI/CD for Code Coverage with GitHub Actions

Implementing JaCoCo Code Coverage in Android Projects
Implementing JaCoCo Code Coverage in Android Projects

It’s a Part 2 of Implementing JaCoCo Code Coverage in Android Projects.

The final goal of this step is to establish a GitHub Actions CI/CD pipeline that automatically executes unit tests and generates JaCoCo code coverage reports upon pull requests in your Android project.

Set up a CI/CD pipeline using GitHub Actions to automate the testing and code coverage process.

name: Tests

on:
  pull_request:

jobs:
  unit-tests:
    name: Unit Tests
    runs-on: ubuntu-20.04
    permissions:
      pull-requests: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Run test
        run: ./gradlew testDebugUnitTest

      - name: Upload tests results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-unit
# You need to add all the paths for which you want to create code coverage.
# */build/outputs/** -> path where the .exec file is generated
# */build/tmp/kotlin-classes/** -> the location of compiled Kotlin classes
          path: |
            */build/outputs/**
            */build/tmp/kotlin-classes/**

  code-coverage:
    name: Merged code coverage
    runs-on: ubuntu-20.04
    permissions:
      pull-requests: write
    needs:
      - unit-tests

    steps:

      - name: Checkout
        uses: actions/checkout@v4

      - name: Download tests results for both jobs
        uses: actions/download-artifact@v4
        with:
          name: test-results-unit

      - name: Run code coverage
        run: ./gradlew codeCoverage

      - name: Store HTML coverage report
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report
# The path where JaCoCo code coverage should be stored.
          path: |
            */build/reports/jacoco/codeCoverage

Currently, you should be able to download the html code coverage report from artifacts after creating a pull request.

To be more fancy, you can add the coverage to your PR!

First, add this configuration to module-jacoco.gradle to generate a code coverage report in xml format.

tasks.register('codeCoverage', JacocoReport) {

    reports {
        html.required.set(true)
        xml.required.set(true)
    }
...
}

Then, you can add step to your already configured workflow and create the xml report in your pull request.

...
      - name: Store HTML coverage report
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report
          path: |
            */build/reports/jacoco/codeCoverage

            - name: Add coverage to PR
        id: jacoco
        uses: madrapps/jacoco-report@v1.6.1
        with:
# Paths of the generated jacoco xml files.
          paths: |
            */build/reports/jacoco/codeCoverage/codeCoverage.xml
          token: ${{ secrets.GITHUB_TOKEN }}

We used https://github.com/Madrapps/jacoco-report for this, so for more details and customization I recommend visiting the GitHub repository.

Currently, you should be able to see the xml code coverage report in your pull request.

xml coverage

You can check the entire project with JaCoCo implemented and more here.

Conclusions

Setting up a CI/CD pipeline with GitHub Actions for code coverage with JaCoCo provides a streamlined and automated way to ensure code quality. This process not only makes it easier to catch bugs and issues early in the development cycle, but also promotes best practices for code health. Ultimately, this leads to more robust and reliable software.