CodeBuildでRSpecのテストレポートを表示する

はじめまして。サーバーサイドエンジニアの kinakobo です。

唐突ですが、自動テストの実行にはどんなCIツールを使用していますか?

色々と選択肢があると思いますが、自分は今までCircleCI、GitHub Actionsを使うことが多く、ANDPADに入社して初めてCodeBuildでテストを実行しました。
それまでCodeBuildを使ったのはDocker imageの構築くらいだったので、あまりテストの実行に向いている印象は持っていませんでした。

ですが調べてみると意外と機能が充実しており、中でもテストレポート機能は便利だと思ったので今回紹介したいと思います。

テストレポート機能とは

AWS CodeBuild でのテストレポートの使用 - AWS CodeBuild

テストレポート機能は、テストのレポートファイルをいい感じに整理して表示してくれる機能です。 CircleCIにも似たような機能があるので、使ったことがある方はイメージつきやすいかもしれません(テスト メタデータの収集 - CircleCI

また、テストのレポートだけでなくコードカバレッジのレポートも最近表示してくれるようになりました。

以降はテストレポート機能のうち、テストレポート、コードカバレッジレポートに分けて順番に紹介していきます(名称がややこしいですね)

テストレポート

まずはテストレポートについて紹介します。 レポートファイルの形式は様々なものがサポートされており、今回はその中からJUnit XMLを使用します。

前提: CodeBuildとRSpecの実行環境は用意できているとして割愛します。

それではまずは .buildspec.yml を以下のように編集します。

version: 0.2

phases:
  install:
    runtime-versions:
      ruby: 2.6
  pre_build:
    commands:
      - gem install rspec # 実際はGemfileに記述していることが多いと思うので bundle install などで読み替えてください
      - gem install rspec_junit_formatter
  build:
    commands:
      - rspec <test source directory>/* --format RspecJunitFormatter --out <test report directory>/<report filename>
reports:
  rspec_reports:
    files:
      - <report filename>
    base-directory: <test report directory>
    file-format: JunitXml

RSpec を使用したテストレポートのセットアップ - AWS CodeBuild から引用)

重要な箇所をピックアップしますと、下記でRSpec実行時にJUnit XML形式のテストレポートファイルを生成し、

--format RspecJunitFormatter --out <test report directory>/<report filename>

下記でCodeBuildで読み込むテストレポートファイルのパスと形式を指定しています。

reports:
  rspec_reports:
    files:
      - <report filename>
    base-directory: <test report directory>
    file-format: JunitXml

.buildspec.yml を用意したらCodeBuildを実行して、完了するとレポートが生成されます。
生成されたレポートはレポートタブに表示されます。

f:id:kinakobo:20200910220401p:plain

レポートのリンクをクリックすると、レポートの詳細画面に遷移します。

f:id:kinakobo:20200910220835p:plain

ここではパスレートやテストケースの一覧を確認できます。
コケたテストは一覧の一番上に表示されるので一目で特定できます。

画面左上の「レポートグループを表示」ボタンをクリックするとレポートグループの詳細画面に遷移します。

f:id:kinakobo:20200910221553p:plain

ここでは過去のテストのパスレートや実行時間の経過を確認できます。
個人の適当なリポジトリを使用したので、面白みのない数値になっていますがグラフの見た目はなんとなく伝わるかと思います。

基本的な使用方法はここまでの通りで、弊社の場合はテストを並列実行するために parallel_tests を使用しているため、設定値を次のように変更しました。

まず、JUnit XML形式のレポートを出力するため、 .rspec_parallel ファイルに以下を追加します。(参考: https://github.com/grosser/parallel_tests/wiki#with-rspec_junit_formatter----by-jgarber

--format RspecJunitFormatter --out tmp/rspec<%= ENV['TEST_ENV_NUMBER'] %>.xml

次に buildspec.ymlreports: を以下のように記述して、複数のxmlファイルを認識させるようにします。

reports:
  rspec_reports:
    files:
      - rspec*.xml
    base-directory: tmp
    file-format: JunitXml

あとはCodeBuildを実行すれば先ほどと同じようにレポートが生成されます。 並列実行した場合でもレポートは1つにまとめて表示されました。

コードカバレッジレポート

続いてコードカバレッジレポートについて紹介します。
こちらは現時点で4つのファイル形式がサポートされており、今回はSimpleCovを使用してみます。

まずは simplecov gem をインストールして、spec/spec_helper.rb に以下を追記します。

require 'simplecov'

SimpleCov.start do
  enable_coverage :branch # CodeBuildのレポートはブランチカバレッジをサポートしているため有効化する
end

次に .buildspec.ymlreports: に追記します。設定項目は先ほどのテストレポートと同様で、値だけ異なります。

reports:
  rspec_reports:
    ...
  simplecov_reports:
    files:
      - .resultset.json
    base-directory: coverage # デフォルトの出力箇所。SimpleCov.coverage_dir で変更可能。
    file-format: SimpleCov

CodeBuildを実行するとコードカバレッジレポートが生成されます。

f:id:kinakobo:20200911082948p:plain

レポートのリンクをクリックして詳細を開くと、円グラフが表示されます。

f:id:kinakobo:20200911084112p:plain

左の円グラフが「ラインカバレッジ」で右の円グラフが「ブランチカバレッジ」になります。 これらの違いは、

number.odd? ? "odd" : "even"

このような三項演算子のコードをテストする時、「ラインカバレッジ」は条件を評価するだけで100%カバーしたことになりますが、 「ブランチカバレッジ」では両方の条件を満たさないと100%カバーしたことになりません。後置ifなどについても同様です。

こう書くと「ブランチカバレッジ」だけで良さそうな気がしますが、「ブランチカバレッジ」は条件文のみに関係するので、条件のないコードにはラインカバレッジが必要です。 ですので両方を確認するのが良いです。
詳しくはAWSのドキュメントsimplecovのドキュメントを参照してください。

今回使用した私のリポジトリでは、ブランチカバレッジが26%なので条件分岐のテストが甘いのが丸わかりですね!

続いて画面左上の「レポートグループを表示」ボタンをクリックするとこのような表示になります。

f:id:kinakobo:20200911095420p:plain

こちらもテストレポートと同様に今までの経過を確認できます。 コードカバレッジについては単体のレポートよりこちらの経過を見ることの方が多くなりそうです。

codecovなどのサービスに比べれば機能が少ないかもしれませんが、追加料金なしで使えるという面では十分有用だと思いました。

さいごに

AWSの公式を読めば知れるような内容でしたが、案外知られていない機能なのかと思い記事にしてみました。 自分は最近までレポート機能の存在を知らずにCodeBuildを使っていたので、同じような方の参考になりますと幸いです。
最近並列実行がサポートされたりと、どんどん便利になってきているCodeBuildに今後も注目していきたいです。

ANDPADでは、一緒に働く仲間を募集中です!

engineer.andpad.co.jp