Studyplus Engineering Blog

スタディプラスの開発者が発信するブログ

CircleCIのrerun failed testsを有効化してみる

ウェブアプリケーショングループのましばです。
ようやく暖かくなってきましたが、まだまだ気候が安定しませんね。

今回はCircleCIにきていたrerun failed testの機能を使ってみた話です。

Flakyなテスト

プログラミングを実装する際にテストを書いていく中で、普段は成功していてもまれに失敗するテスト(いわゆるFlaky Test)が発生します。
割と世界中で悩みになっているようでして、弊社のプロダクトにも存在して偶に引っかかることがあります。
そういった際はCIでテストをやり直すことになるのですが、このコストがなかなか大変だったりします。

rerun failed tests機能

そんな中、CircleCIにrerun failed testsという機能がプレビューで追加されていました。

"Re-run failed tests only (失敗したテストのみの再実行)" オプションでは、新しいコミットではなく同じコミットで失敗したテストを再実行できます。

とあるように、テストが失敗した際にすべてのテストケースを再実行するのではなく、失敗したテストのみを再実行することができるようになる機能です。

試してみる

ドキュメントがしっかり整備されているのでそれに従うだけで実装できます。 今回はJestの場合を試してみます。

https://circleci.com/docs/ja/rerun-failed-tests/#configure-a-job-running-javascript-typescript-jest-tests

まずはテスト実行結果をjunit形式で保存するjest-junitを追加します。 (ドキュメントではCIの中で追加していますが、package.jsonに追加しても良いと思います)

その後テストを実行します。
弊社の場合、circlleci tests globを利用したり、テストカバレッジを出したりしているので若干ドキュメントと差異があります。
ドキュメントにあるように、circleci tests run --command="..."を使うのが今回のメインの部分です。

- run:
    command: |
       circleci tests glob 'src/**/*.test.{ts,tsx}' | \
       circleci tests run --command=“JEST_JUNIT_ADD_FILE_ATTRIBUTE=true xargs npx jest --config jest.config.js --runInBand --coverage --ci” --verbose --split-by=timings
    environment:
      JEST_JUNIT_OUTPUT_DIR: ./reports/
  - store_test_results:
      path: ./reports/

この状態でテストを実行し、何らかの失敗したテストケースが存在する場合、Rerun内からRerun failed testsが選択できるようになります。
これを選ぶことで、すべてのテストではなく失敗したテストケースのみが再度実行できます。

再実行すると以下のようなログが出力され、失敗したテストのみが実行されていることがわかります。

received failed tests from workflow xxx
3 test(s) failed out of 1234 total tests. Rerunning tests from 2 file 

分割実行している場合の注意点

テストを分割実行したあとにカバレッジを集計するような処理を行っている場合、再実行するとカバレージレポートのファイルが存在せず、カバレッジが正しく集計できないことがあります。
そのような場合は、テストカバレッジをキャッシュしておく設定を追加する必要があります。
こちらは英語版のドキュメントには記載がありますが、日本語訳はまだのようです。
(チームメンバーが発見して対応してくれました)

- restore_cache:
    key: coverage-{{.Revision}}-{{.Environment.CIRCLE_NODE_INDEX}}
- save_cache:
    key: coverage-{{.Revision}}-{{.Environment.CIRCLE_NODE_INDEX}}
    paths:
      - coverage_file_directory
    when: always

終わりに

今回はCircleCIのプレビュー版の機能を少し試してみました。
プレビュー版ではありますが現状でも十分使える機能になっています。
flakyなテストで悩んでいる方は利用を検討してみてはいかがでしょうか。