🗂

Ruby + GitHub Actions + Codecovでカバレッジを可視化する

2022/02/22に公開

はじめに

こんにちは、M-Yamashitaです。

今回の記事は、Codecovを使用したカバレッジ測定の導入方法の話です。
開発においてテストコードも必要となってきている中、今持っているテストがどの程度コードを網羅できているのか知りたいと思いませんか。
本記事ではRuby、GitHub Actions、Codecovを組み合わせ、カバレッジを可視化する方法を紹介します。また、その組み合わせを使用した際に経験したエラーも含めて紹介します。

伝えたいこと

  • Ruby、GitHub Actions、Codecovの連携方法
  • Pull Request上やCodecov上でカバレッジを確認する

背景

指定ブランチのカバレッジやコード変更によるカバレッジの変化を可視化するサービスとして、Codecovがあります。
https://about.codecov.io/

このサービスを手持ちのリポジトリやCIと連携させるために、Codecov公式による説明や、多くの連携記事が投稿されています。

本記事執筆以前、私は手持ちのRubyリポジトリとGitHub Actions、Codecovを連携させたかったのですが、Ruby、GitHub Actions、Codecovを組み合わせた構築記事はあまりないように思われました。
そのため類似の構築記事を参照しながら構築しましたが、選定ツールの違いの解消や、選定したツールによるエラーの解決のために時間がかかってしまいました。
今後、私も含めた別の人が同じツールで構築しようとした際、なるべく楽に進められるよう手順として残したいと思い、この記事を投稿しました。

使用環境

  • Ruby: 2.7.4
  • RSpec: 3.11.0
  • Codecov
  • GitHub Actions

連携

以下の手順を行っていくことで連携できます。

  • CodecovとGitHubとの連携
  • SimpleCov, simplecov-coberturaの使用
  • GitHub Actionsを使用してCodecovへアップロード

各手順について説明します。

CodecovとGitHubとの連携

Codecovのトップ画面からGitHubでログインします。

認可を求められるので許可します。

これにより、CodecovがGitHubに対してアクセス権を持つようになりました。

次に、CodecovのOverview画面に該当リポジトリを表示させるための設定が必要となります。この設定はGitHub上で行います。
GitHubの個人ページのSettingsを開き、Settingsページ下部にあるIntegrationsのApplicationを開くと、Codecovが表示されます。このCodecovのConfigureページを開きます。

このConfigureページのRepository access項目で、CodecovのOverview画面に表示させたいリポジトリを選択し、保存します。

Codecovを適用したいリポジトリがpublicリポジトリの場合、GitHubとCodecovの連携設定はここまでとなります。
privateリポジトリの場合は、カバレッジ測定結果をアップロードするため、下記のCodecovトークンの設定が必要となります。

Codecov上のリポジトリからSettingsを選びトークンをコピーします。

このCodecovトークンを、GitHub上のprivateリポジトリに、環境変数のシークレットとして保存します。図ではCODECOV_TOKENとして保存しています。

Codecovのトークンの設定はここまでとなります。なお、このCODECOV_TOKENは後述のGitHub Actionsで使用します。

SimpleCov, simplecov-coberturaの使用

リポジトリにSimpleCov、simplecov-coberturaのgemを取り入れます。
https://github.com/simplecov-ruby/simplecov
https://github.com/dashingrocket/simplecov-cobertura
SimpleCovはカバレッジの測定とカバレッジのレポート出力、simplecov-coberturaはCodecov向けのレポートを出力するgemとなります。
これらのgemとコードをGemfile、spec_helper.rbに追加します。

Gemfile
gem 'simplecov', require: false
gem 'simplecov-cobertura'
# この2行はspec_helper.rbの最初に書くこと
require 'simplecov'
SimpleCov.start

require 'simplecov-cobertura'
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter

この設定により、RSpec実行時にカバレッジを測定し、Codecovへアップロードするためのカバレッジレポートができるようになりました。

GitHub Actionsを使用してCodecovへアップロード

最後に、カバレッジレポートをCodecovへアップロードする手順について紹介します。

CodecovへアップロードするGitHub Actionsとして、Codecov GitHub Actionがあります。
https://github.com/marketplace/actions/codecov

このアクションを使用して以下ワークフローを作成します。

workflow.yml
on: [pull_request]

jobs:
  job:
    runs-on: ubuntu-latest
    name: Run spec
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Set up ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.7.4
          bundler-cache: true

      - name: Test with RSpec
        run: |
          bundle exec rspec

      - name: Upload coverage reports
        uses: codecov/codecov-action@v2
        with:
          token: ${{ secrets.CODECOV_TOKEN }} # 対象リポジトリがpublicリポジトリならばトークン不要
          files: ./coverage/coverage.xml
          flags: unittests
          name: ruby-sample-for-codecov
          fail_ci_if_error: true

Codecov GitHub Actionの使用において、対象リポジトリがpublicリポジトリならば、トークンのセットは不要です。セットされていても問題ありません。
ただし、対象リポジトリがprivateリポジトリならば、上記で作成したCODECOV_TOKENのセットが必要です。

手順は以上となります。これでカバレッジ測定とCodecovへのアップロードの環境が整いました。

連携結果

Pull Request時のカバレッジ表示

Pull Requestを作成し、GitHub ActionsのワークフローでCodecovへのアップロードが完了すると、Codecovのbotがカバレッジの測定結果をPull Requestにコメントします。

Codecov上のカバレッジ表示

Settings画面でデフォルトブランチを指定していると、Overview画面にそのブランチのカバレッジが表示されます。

特定ブランチのカバレッジを見たい場合は、Branches画面でブランチを選択することで
カバレッジを確認できます。

連携時の疑問やエラー

Codecov連携の環境構築時、私が感じた疑問や体験したエラーについて記載します。

deprecatedとなったCodecov Ruby Uploaderのgemの代替として何を使うか?

2022年2月1日までは、カバレッジレポートを出力しCodecovにカバレッジレポートをアップロードするgemとして、Codecov Ruby Uploaderを使うことができました。
https://github.com/codecov/codecov-ruby
ただし、このgemは2022年2月1日にdeprecatedとなっており、このgemを使用したアップロードはいずれできなくなるようです。

On February 1, 2022 this uploader will be completely deprecated and will no longer be able to upload coverage to Codecov.

Codecov Ruby Uploaderが担っていた以下2つの機能は、上記の連携手順にもあるように、それぞれgemやGitHub Actionsで代替可能です。

  • カバレッジレポートの出力: simplecov-coberturaのgem
  • カバレッジレポートをCodecovへアップロード: CodecovのGitHub Actions

カバレッジが正確に測定されない

RSpec実行時、カバレッジが測定されず、以下のようにカバレッジが空になっていることがありました。

coverage.xml
<?xml version='1.0'?> 
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<!-- Generated by simplecov-cobertura version 2.1.0 (https://github.com/dashingrocket/simplecov-cobertura) -->
<coverage line-rate="0" lines-covered="0" lines-valid="0" complexity="0" version="0" timestamp="1645222950">
  <sources>
    <source>/xxxxx/M-Yamashita01/RubySample</source>
  </sources>
  <packages/>
</coverage>

※空になるパターンもあれば、一部だけ計測されていないパターンもあります。

これはspec_helper.rbに記載するSimpleCovの位置に問題があるためです。
SimpleCovのREADMEに注意書きがあります。

Load and launch SimpleCov at the very top of your test/test_helper.rb (or spec_helper.rb, rails_helper, cucumber env.rb, or whatever your preferred test framework uses):

require 'simplecov'
SimpleCov.start

# Previous content of test helper now starts here

Note: If SimpleCov starts after your application code is already loaded (via require), it won't be able to track your files and their coverage! The SimpleCov.start must be issued before any of your application code is required!

この注意書きからわかるように、spec_helper.rbの最上部にSimpleCov.startのコードがなければ、カバレッジを正常に測定できません。

参考リンク:
https://stackoverflow.com/questions/35476814/simplecov-calculate-0-coverage-for-user-model

なお、カバレッジが空だったレポートをCodecovにアップロードした場合、以下のようにNo repository activation requiredと表示されます。

カバレッジ測定結果にてベースブランチが?になる

Codecovのbotのコメントにて、ベースブランチ(画像ではmaster)のカバレッジが?になる場合があります。

この現象に関しては、Codecovのドキュメントに類似のエラーについての記載があります。
https://docs.codecov.com/docs/error-reference#missing-head-commit

You will see an error stating No coverage uploaded for pull request head. when the pull request has:

  • not yet uploaded coverage results to Codecov;
  • or the uploaded reports are from failed CI builds.

このドキュメントではPull Request内のheadコミットについてなので、これをbaseに置き換えて読み解くと、
「Pull Requestのベースブランチのコミットでカバレッジがアップロードできていない。
これは、カバレッジレポートをCodecovにアップロードしていない、もしくは失敗したCIビルドでレポートがアップロードされている。」
となります。

この解消方法は、カバレッジレポートをCodecovへアップロードしたコミットが、ベースブランチに入ることで解消されます。

CodecovのOverview画面で結果が表示されない

テスト、Codecovへのアップロードが成功したにもかかわらず、CodecovのOverview画面で結果が表示されず、No repository activation requiredの画面のままになっていることがあります。
この原因として、以下3つが考えられます。

  • Codecovへカバレッジレポートをアップロードしたが、表示に時間がかかっている
  • アップロードしたカバレッジレポートに、カバレッジが何も記載されていない
  • Codecov上でのデフォルトブランチが、カバレッジレポートがアップロードされていないブランチとなっている。

1つ目の場合は、Codecovの状態にもよりますが、しばらく待てば解消されます。
2つ目だった場合の解消方法は前述の「カバレッジが正確に測定されない」のとおりです。
3つ目に関しては、Overview画面のカバレッジは、CodecovのリポジトリのSettings画面で指定したデフォルトブランチのカバレッジとなります。
そのため、指定したデフォルトブランチでカバレッジレポートがアップロードされていなければ、Overview画面でカバレッジが表示されません。
デフォルトブランチでカバレッジがアップロードされていれば、表示されるようになります。

おわりに

この記事ではRuby、GitHub Actions、Codecovを組み合わせてカバレッジの可視化を行いました。
可視化により漠然と見えていたものが数値としてはっきり見えるようになるので、次のアクションや意思決定に繋げやすくなるのではないかと思われます。
この記事が誰かのお役に立てれば幸いです。

その他参考資料

・Codecov公式によるCodecovの始めかた
https://docs.codecov.com/docs#getting-started

・環境構築時の参考リポジトリ
https://github.com/codecov/ruby-standard-2

Discussion