Add test coverage badge for PHP and Pest in your GitHub repository
Tags: php, github, testing, codequality
Published: 2021-12-20 21:39:48

If you walk through across GitHub repositories, you can see that most of them show some badges. A badge is a sort of icon that show you the status of your code, your repository, your workflow, etc.

In your Readme file in your GitHub repository, you can include your badges.
![Test coverage badge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh22cjyqvf9y9ewqnpip.png)

Badges are for:
- show package version;
- number download;
- issues information (totals, opened, closed ...);
- result of test executions;
- result from GitHub Actions workflows;
- etc...

A good website where to generate badges is https://shields.io/

If you don't find a badge that fits your need, you can create one, or you can use some tools specific for your needs.
In my last project, I needed to measure the test code coverage.

> Code coverage is the percentage of code which is covered by automated tests. Code coverage measurement simply determines which lines of code / instructions have been executed through a test run, and which lines / instructions have not. The percentage is calculated based on code covered and all code (number of lines of code).

Normally, the result is shown in the terminal if your test suite is executed in a terminal, for example via command line.
You have also the option to save the result in some specific file with a "standard" format.
For example, "clover" format is an XML file that reports code coverage e some other nice metrics.
If you run the test suite in your GitHub Actions workflow, you need a specific action that is able to read clover format and use the value of coverage to render a badge.
Then a badge needs to be committed to the repository.
To recap:
- execute test in GitHub Actions workflow;
- save the report in clover format (clover.xml file);
- use an "Actions" that: read the clover.xml file, produces the badge and commit/push the new badge on the repository.

In the Readme file, you need to include the badge image.

## Execute test in GitHub Actions workflow
To execute tests, you can use PHPUnit or Pest. Both tools have the option for saving the report in *clover* format (Pest uses the feature provided by PHPUnit).

```yaml
      - name: Execute tests (Unit and Feature tests) via PestPHP
        run: vendor/bin/pest --coverage-clover clover.xml
```
In this way, the *clover.xml* file is created.

## Create a badge

For creating the badge, I found this Actions: [phpunit-coverage-badge](https://github.com/marketplace/actions/phpunit-coverage-badge).

This actions:
- reads clover.xml file;
- saves the badge file *coverage_badge_path*;
- optionally, commits and pushes the badge via *push_badge* option;
- for pushing the badge to the repo you need to set the *repo_token*.

```yaml
      - name: Generate test coverage badge
        uses: timkrase/phpunit-coverage-badge@v1.2.0
        with:
          coverage_badge_path: 'badge-coverage.svg'
          push_badge: true
          repo_token: ${{ secrets.GITHUB_TOKEN }}
```

Now, every time you push your code on *main* branch, the test suite is executed and the badge is updated.

## Update Readme file
Now that the badge file is created, you need to include it into your readme file with the typical markdown syntax for images:

```markdown
[![Test Coverage](https://raw.githubusercontent.com/Hi-Folks/array/main/badge-coverage.svg)](https://packagist.org/packages/hi-folks/array)
```
You need to replace *Hi-Folks/array* with your *org/repo* of your project.
The current badge is:
[![Test Coverage](https://raw.githubusercontent.com/Hi-Folks/array/main/badge-coverage.svg)](https://packagist.org/packages/hi-folks/array)

## The workflow file
The whole yaml file (you need to save it in .github/workflows directory):

```yaml
name: Test Coverage PHP Package
on:
  push:
    branches:
      - main

jobs:
  laravel-tests:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        operating-system: [ubuntu-latest]
        php-versions: [ '8.0' ]

    name: P${{ matrix.php-versions }} - L${{ matrix.laravel }} - ${{ matrix.operating-system}}

    steps:
      - uses: actions/checkout@v2
      - name: Install PHP versions
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
      - name: Install Dependencies
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

      - name: Show dir
        run: pwd
      - name: PHP Version
        run: php --version

      # Code quality

      - name: Execute tests (Unit and Feature tests) via PestPHP
        # Set environment
        env:
          SESSION_DRIVER: array
        run: vendor/bin/pest --coverage-clover clover.xml

      - name: Generate test coverage badge
        uses: timkrase/phpunit-coverage-badge@v1.2.0
        with:
          coverage_badge_path: 'badge-coverage.svg'
          push_badge: true
          repo_token: ${{ secrets.GITHUB_TOKEN }}
```