Now in REALITY Tech #67 Goプロジェクトのテストカバレッジ向上を実現するGitHub Actionsの活用

こんにちは!REALITY プラットフォーム事業部サーバチームのFujitaです。今回の記事では、GitHub Actionsを活用してプルリクエスト毎にテストカバレッジレポートを自動生成し、コメントとして表示する方法を紹介します。

テストカバレッジとは?

テストカバレッジは、ソフトウェア開発において、テストがどの程度ソースコードをカバーしているかを示す重要な指標の一つです。Go言語においても、テストカバレッジの維持・向上は品質保証に非常に重要です。高いテストカバレッジは、機能の信頼性とバグ発見のしやすさに寄与し、品質の維持や向上に役立ちます。ただし、高いカバレッジが必ずしも品質の高さを保証するわけではないため、適切な基準とバランスを見極めることが重要です。

Go言語におけるテストカバレッジの取得方法

Go言語では、go test コマンドを使用してテストを実行し、テストカバレッジを計算することができます。具体的には、以下のコマンドを実行することで、テストカバレッジの情報を取得できます。

// bash
go test -cover ./...

また、テストカバレッジの情報をファイルに出力し、HTML形式で表示することもできます。

// bash
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html

GitHub Actionsの設定方法

自動で取得する方法として、GitHub Actionsを設定するためのYAMLファイルを作成し、PRが作成された際にテストが実行され、テストカバレッジ情報が取得されるように設定を行います。そして、GitHub Actionsで取得したテストカバレッジ情報を、PRにコメントとして表示します。

まず、テストカバレッジレポートを用いて、各パッケージごとのカバレッジ情報を表示する目的で、coverage.txtというファイルを生成し、対象情報を抽出する方法です。makeコマンドを使って、下記のようなcoverage.txtを作成します。

// Makefile
coverage:
        go test -short -v -covermode=count -coverprofile=coverage.out | tee test_output.txt
	go tool cover -func=coverage.out | awk '/total:/ {print "| **" $$1 "** | **" $$3 "** |"}' | tee coverage.txt
	cat test_output.txt | grep 'ok.*coverage' | awk '{sub("github.com/your/package/", "", $$2); print "| " $$2 " | " $$5 " |"}' | tee -a coverage.txt
	echo "## Test Coverage Report" > coverage_with_header.txt
	echo "| Package           | Coverage |" >> coverage_with_header.txt
	echo "|-------------------|----------|" >> coverage_with_header.txt
	cat coverage.txt >> coverage_with_header.txt
	mv coverage_with_header.txt coverage.txt
	cat coverage.txt

このMakefileのcoverageターゲットは、Goプロジェクトのカバレッジ情報を取得し、全体とパッケージごとのカバレッジをテーブル形式で表示します。coverage.outから全体のカバレッジ情報をawkで整形し、grepはパッケージごとのカバレッジ抽出に使用しています。

coverage.txtの中身は下記のような形です。

// coverage.txt
## Test Coverage Report
| Package           | Coverage |
|-------------------|----------|
| total | 80.0% |
| PackageName | 70.0% |
| PackageName | 60.0% |
| PackageName | 80.0% |
...

GitHub Actionsでのレポート表示

GitHub Actionsのワークフロー内でテストカバレッジレポートを生成した後、コメントとしてプルリクエストに表示させる方法がいくつか存在します。例えば、外部サービスを利用してコメントを投稿するアクションを使う方法や、GitHub APIを直接呼び出してコメントを投稿する方法などがあります。どちらの方法を選んでも、プルリクエストで迅速にテストカバレッジ情報を確認できるため、品質の維持や向上に役立ちます。

サンプルコードしては下記のような形です。

// yaml
name: coverage
on: pull_request
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - uses: actions/setup-go@v3
        with:
          go-version: 1.18.0
      - name: run coverage
        run: |
          make coverage
      - name: Find existing comment
        id: find_comment
        uses: peter-evans/find-comment@v2
        with:
          issue-number: ${{ github.event.number }}
          body-includes: "## Test Coverage Report"
      - name: Delete existing comment
        if: steps.find_comment.outputs.comment-id
        run: |
          curl \
            -X DELETE \
            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            -H "Accept: application/vnd.github+json" \
            "https://api.github.com/repos/${{ github.repository }}/issues/comments/${{ steps.find_comment.outputs.comment-id }}"
      - name: Comment coverage on PR
        uses: peter-evans/create-or-update-comment@v3
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.number }}
          body-path: 'coverage.txt'

今後の展望とまとめ

チームや開発コードの規模が拡大し、全体を把握することが難しくなってきています。テストはコードの品質を確保するために重要な手段ですが、現状ではまだ十分なテストが書かれていない状況です。これまでにもテストの自動化に取り組んできましたが、今後はテストカバレッジの目標を設定し、より一層の取り組みが必要だと考えています。

テストカバレッジの数値目標の策定とは、適切なテストカバレッジの目標値をチーム全体で設定し、その達成に向けて努力していくことです。そのためには、テストを皆に書いてもらうためにベストプラクティスをまとめ、テストカバレッジ向上の取り組みを通じて、チーム全体で継続的に学習し、改善活動を行っていく必要があります。また、他のチームや業界のベストプラクティスも参考にし、品質向上に役立つ情報を積極的に取り入れようと思います。

まとめとして、GitHub Actionsを使ったテストカバレッジレポートの自動生成は、品質向上や効率化に非常に有益であることが実感できました。今後もこの取り組みを続けながら、チームの品質意識と開発の効率をさらに向上させていくことが重要であると考えています。

弊社では、こういった改善からもREALITYをより良くしていくことに興味があるエンジニアを大募集しています!ご応募お待ちしております!

以下のGoogle Formからスカウトを待つこともできますので、是非ご応募ください!
https://docs.google.com/forms/d/e/1FAIpQLSeIJrmkWuk-MIpz5jGpQvkASvM7-krypPTF0fgNAaEI9OVUbQ/viewform