rspecに潜む、flaky testを可視化したい ~ReportPortal編~

こんにちは。SREチームの程です。 つい先日、自宅近くのKALDIコーヒーショップにて、コーヒー豆半額セールをやっていたので大量爆買いを敢行しました。コーヒー豆だけではなく、全品10%引きという大変そそられるセールのおかげで、次のクレジットカードの支払明細を見るべきか、あえてここは見ぬふりをするか決めかねています。これからお正月にかけて何かと出費が増える時期かと思いますので、どうか皆様に置かれましてもご注意くださいませ。

なお、本記事は以下記事の続編となります

techblog.kiramex.com

概要

自動テストのOSSレポーティングツールのひとつである ReportPortal を使ってrails rspec(自動テストフレームワーク)の Flaky testを発見する方法について解説します。

やりたいこと

  • CI(github actions)環境で実行させたrails rspecの自動テスト結果をReportPortalサーバーに送信する
  • ReportPortalダッシュボードで自動テストの実行結果を確認し、flakyなテストを探す

セットアップ

前提

  • AWSのEC2上でReportPortalサーバーをホストする。サーバードメインは本記事内ではサンプルとしてreportportal.example.comと表記する。
  • EC2内にdockerがインストールされており、dockerdが起動している。
  • EC2内にdocker-composeコマンドがインストールされている。

設定

ReportPortal の公式サイト上に記載の手順(https://reportportal.io/installation)を追っていけば基本的にはOKです。 ざっくりと以下内容になります。

  • Docker版ReportPortalをインストール
  • 各言語やテストフレームワークに対応するAgentをインストール

Docker版ReportPortalをインストール

以下URLに記載の手順でReportPortalをインストールします。すでにReportPortal側でdocker-compose.ymlが用意されているので、基本的にはそれをダウンロードして docker-compose up するという流れになります。なお、Kubernetes版のReportPortalも用意されているようなので、本格的にシステムの運用フローに取り入れたい場合などはそちらをご利用いただくという選択肢もありでしょう。

https://reportportal.io/docs/Deploy-with-Docker

ruby用のagentをインストールする

こちらも設定は簡単で、以下レポジトリ内READMEに記載の手順に従えばOKです。

GitHub - reportportal/agent-ruby: Agent - Ruby Cucumber and RSpec formatters

おおまかには以下の手順となります。

  • ReportPortal Agent用のGemをGemfileに追加する (gem install reportportal)

  • report_portal.yaml.example(以下リンク)を、自分のrubyプロジェクト内に config/report_portal.yaml としてコピーする。

agent-ruby/report_portal.yaml.example at master · reportportal/agent-ruby · GitHubgithub.com

※ なお、コピー先ディレクトリとして使用可能な場所は '.', './.config', './config' の3か所

  • コピーしてきた config/report_portal.yaml 内の設定項目を編集する。
    • endpoint: http://reportal.example.com:8080
      • ReportPortalがホストされているサーバーURL。
      • ReportPortalはデフォルトで8080番ポートでホストされています。
      • DNS上でAWSのEC2のパブリックIPに適当なドメインを紐付け、それを使っています。
    • launch: server.yml
      • 自動テストの各実行回ごとにつけられる名前。
      • 繰り返し同じ自動テストを実行している状況で実行回を識別したいというケースでは、ここに毎回一意な名前を入れるとわかりやすくなりそうです。
      • 今回は固定文字列を入れておきます。
    • project: default_personal
      • プロジェクト名。
      • 今回はデフォルトで入ってる名前をそのまま使いました。
    • attributes: key1:value1
      • 自動テストの実行結果に対して、キーバリュー形式で追加情報をタグ付けできます。
      • 今回はデフォルト値のままにしました。

あとは、rspec <other options> -f ReportPortal::RSpec::Formatter のようにrspecを実行するだけで、テストの実行結果がReportPortalに自動で送信されるようになります。

テスト実行

CIでrspec自動テストを実行させる

もともと今回はCI上で実行させているrspec上でflaky testが発生していました。弊社CI環境はgithub actionsを利用しているので、github actionsのワークフロー上で実行させているrspec実行結果をReportPortal上で反映できるようにさせておきます。

以下に今回使用したワークフローファイルの抜粋版を示します。特に一番最後のstepにて、rspecの実行とReportPortalへのデータ送信を実行させています。なお、各stepの内容は、namerunの内容を見ていただければ、ある程度推測がつくかと思いますので、詳細な説明は省略させていただきます。

    steps:
    - uses: actions/checkout@v2
    - name: Setup Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: ${{ env.RUBY_VERSION }}
    - name: Install required package
      run: |
        apt-get update
        apt-get install --yes build-essential nodejs
    - name: Install gems
      env:
        RAILS_ENV: test
      run: |
        bundle config path vendor/bundle
        bundle install --jobs 4 --retry 3

    - name: Setup MySQL
      run: |
      <略>

    - name: Run RSpec
      env:
             <省略>
      run: |
        bundle exec rails db:create db:schema:load --trace
        bundle exec rspec  --tag ~@EtoE --format ReportPortal::RSpec::Formatter

ReportPortal画面

さて、それではいよいよReportPortalの画面上で実行結果を確認してみたいと思います。

ログイン画面

http://reportportal.example.com:8080にアクセスするとログイン画面が表示されます。

f:id:tei-krmx:20211111104340p:plain
ログイン画面

https://reportportal.io/installationに記載されている初期パスワードを用いてログインしてみます。

管理画面

ログイン後、ダッシュボードの一覧画面が表示されます。左側に各種機能のメニューがありますが、そのなかからLAUNCHES をクリックします。

f:id:tei-krmx:20211111110034p:plain

何やら自動テストの実行結果らしきものが表示されました。各項目のNameに注目してみましょう。項目名がserver.yml #<Num> となっています。先程、report_portal.yaml設定ファイルで設定した Launch Name が反映されているようですね。#<Num> の部分はおそらく何回目の実行結果かを示しているのでしょう。その他、実行時間やタグなどの情報を見て取ることができます。

続いて画面中央のTTL, PS, FL, SKPに注目します。各項目は次の内容を示しています。

  • TTL = 自動テストの総テストケース数(example数)
  • PS = TTLのうち、成功したテスト数
  • FL = TTLのうち、失敗したテスト数
  • SKP = TTLのうち、スキップしたテスト数

https://reportportal.io/docs/View-launches%3Eviewing-all-launches-latest-launches

すなわち具体的な数値で表現すると、1592個のテストケースのうち、1590個が成功し、2個がスキップされたという結果を示しています。 調べてみると、確かに意図的に実行をスキップさせているテストが2個存在したため、ここで表示されているテスト実行回に限っては問題なく自動テストが実行完了したと考えられます。

f:id:tei-krmx:20211111112406p:plain

それでは、試しに少し下に画面をスクロールしてみましょう。

f:id:tei-krmx:20211111114846p:plain
失敗ケースが含まれている実行回

おや、他の項目とは表示結果が異なる項目がありますね。server.yml #24 の項目に注目してみましょう。 数値を見てみると

FL=1

となっており、1つのテストケースにおいてテストが失敗していることを示唆しています。

この項目をもう少し詳しく見ていきましょう。 FL=1の部分がリンクになっているのでクリックしてみます。

f:id:tei-krmx:20211111115703p:plain

失敗したテストケースが表示されます。複数ある場合は複数表示されるようですが、今回は1つしかないので、それをさらにクリックしてみます。

f:id:tei-krmx:20211111115723p:plain
失敗ケース

失敗しているテストケースの詳細が表示されました。 画面上部に、過去の同じ自動テスト実行における実行結果履歴が表示されています。緑が成功、赤が失敗を表しています。すなわち、過去に実行された4回では成功していたものの、今回なぜか失敗したということがわかります。

f:id:tei-krmx:20211111120321p:plain
失敗ケース詳細

もう少し実行回を重ねてみましょう。71回目における同画面を下記に示します。こちらを見てもやはり本テストケースにおいては概ね成功しているなかで、ごくたまに失敗している様子が見受けられました。

f:id:tei-krmx:20211111121433p:plain
71回目

というわけで本テストケースが限りなく黒に近い、すなわち自動テストを不安定にさせている張本人であろうということが判明しました。

フィルタリング機能

他にもFlakyなテストが存在しないか探してみましょう。先程までは画面をスクロールさせながら目視で失敗しているものがないか確認していましたが、もう少し楽な方法で失敗しているテストがないか探すことはできないのでしょうか。

実はReportPortalには目的のテスト実行結果を探したいときに便利なフィルタリング機能が搭載されています。今回はこちらの機能を活用して失敗しているテストのみを抽出してみたいと思います。

すでに紹介したLAUNCHES画面に戻ります。画面上部を確認してみると Add filter ボタンがあるので押してみましょう。 f:id:tei-krmx:20211111122550p:plain

そうすると、ボタン下部にフィルタリング条件を入力するフォームが出現します。Moreボタンを押すと様々な条件でフィルタリングすることができそうなことがわかります。 f:id:tei-krmx:20211111122812p:plain

この中から、Failed のチェックを付けてみましょう。すると、Enter quantity というフォームが出現するので1つ以上と入力します。おそらく「何テストケース以上失敗している」実行回のみ抽出するといった意味合いなのでしょう。 f:id:tei-krmx:20211111123043p:plain

抽出されました。画面では3回分の実行結果が表示されていますね。あとは先程と同様、FLのリンクから失敗しているケースを確認することができそうです。 f:id:tei-krmx:20211111123454p:plain

ダッシュボード

最後にダッシュボードでFlakyテストを確認する方法をご紹介します。 画面の左側メニューの上から2番目のアイコンをクリックするとダッシュボード画面を作成することができます。 画像ではダッシュボード作成時の案内画面を掲載しています。これを見ると、すでにReportPortal側でダッシュボードウィジェットの雛形がさまざまな形式で準備されているようです。目的用途に合わせたダッシュボードを手軽に構築することができそうですね。 この中に実はすでにFlakyテスト用のウィジェットも用意されていました(画像赤枠)。これを選択してみたいと思います。

f:id:tei-krmx:20211111124446p:plain

ダッシュボードが作成されました。 各テストケース単位でFlakyなテストを一目でわかりやすいように表示してくれています。また、どのテストケースがどれくらいの割合で失敗しているかまで表示してくれているので、Flakyテストの発生頻度をおおまかに掴むこともできそうですね。

f:id:tei-krmx:20211111125047p:plain
Flakyテストダッシュボード

最後に

自動テストにおけるFlakyテストをあぶり出すために活用したツールを紹介してきました。本稿にて紹介したReportPortalでは、様々な言語やテスティングフレームワークに対応しており、何より無料であるため、導入自体のハードルは比較的小さいかと思います。機能面でも、柔軟なテスト結果の分析が可能だったり、テスト結果の管理も同じ画面上でできるため、無料にしては充実した機能が準備されていて幅広いニーズに応えられそうな印象を受けました。ReportPortalの公式サイト上でデモ用のサイト(下記リンク)が公開されているので、興味のある方はぜひ試しに覗いてみてください。

demo.reportportal.io