SmartHR Tech Blog

SmartHR 開発者ブログ

Jest を導入して RSpec と使い分け始めた話

まえがき

こんにちは!SmartHR 基本機能の B チームで開発をしている@ron です。 今回は、私の所属する B チームで品質と開発効率の向上のため Jest を導入するにあたり、チームで行った議論と導入した結果をご紹介します。 Rails を使用している SmartHR では RSpec を使用してテストを実施していますが、テストが増えるにつれて CI での実行が非常に遅くなることが課題となっていました。 Jest を導入したことで、テストの網羅性が上がり、テストパターンを増やしつつ、テストの実行時間の増加を抑えることができました。 また、Jest を導入するにあたり、Jest と RSpec それぞれでどういったテストを書くべきか、どういったテストを書かないべきかを議論し、整理したので、その内容もお話しします。

SmartHR のプロダクト規模について

SmartHR は、企業情報や従業員情報を取り扱うアプリケーション(SmartHR 基本機能)と、その基本機能と連携するかたちで複数のアプリケーションが構成されています。 SmartHR 基本機能の開発チームは 6 つに分かれており、30 人以上のエンジニアが開発をしています。 コードベースは約 72 万行ですが、そのうちプロダクトコードは 14.5 万行で、残りの大部分、つまり約 58 万行(!)は RSpec のテストコードです。 このような巨大なコードベースを複数の開発者で開発しているため、品質を重視した開発が重要となっています。

現状のテスト構成

SmartHR 基本機能の中でも我々のチームでは RSpec と手動テストでテストを実施していました。具体的には、単体テスト(model spec,worker spec など)から API テスト(request spec)、さらには統合テスト(system spec)まで、あらゆるレベルのテストを RSpec で書いています。手動テストは主に新機能のリリース前後や、重要な機能の動作確認のために行われています。

テストに関して抱えている課題

我々のチームがテストに対して感じていた課題は、大きく分けて 2 つあります。

system spec のテストコストが重いため網羅性が低くなりがちであること

model spec や request spec は、テスト対象が小さく、テストコストが軽いため、テストパターンを増やして網羅的なテストを行うことができています。しかし system spec ではテストの実行時間も長くかかり、実装コストも高いため UI 操作やデータの状態に応じた様々なパターンをテストすることが難しいです。 それを補うために、重要で再実行する必要が高い箇所以外は手動テストを行うこともありますが、長期的な視点で見ると、テストの網羅性が低下してしまうことが課題となっています。

テストが増えるにつれて、CI での実行が非常に遅くなること

大量の spec が存在するため、CI でのテスト実行に時間がかかってしまっています。現状、RSpec は CircleCI 上で 100 並列で実行していますが、それでも 15 分ほどの実行時間がかかってしまっています。ブランチを push するたびに待ち時間が発生し、開発効率が低下してしまうのはもちろん、障害発生時など緊急でデプロイなどを行う必要がある際にも時間がかかってしまいます。

チームで考えた解決策

「手動テストを減らし、自動テストの網羅性を高める」ということを目標としてチームで議論を行った結果、フロントエンドのテストを試してみることになりました。 現状で API のテストは網羅的に行えているため、その API をモックした状態で、フロントエンド単体でのテストを十分に行うことができれば、system spec を減らしつつ全体的な品質を向上させることができると考えたからです。

具体的にどう使い分けるのか

system spec と Jest の使い分けをチームで議論した結果、具体的には次のようになりました。

  1. system spec
    • API と連携して動く、基本的な機能の正常系のシナリオテスト
      • 正常系として、受け付けるべき値や状態の場合に、想定通りの挙動をすることを検証します。
    • 不具合が起きるとビジネスインパクトの大きい部分のテスト
      • 例えば情報漏洩に繋がりうる部分など、万が一ミスがあると事業的な影響が大きい部分に対し、必ず自動テストがされるようにします。
  2. Jest
    • API と連携しないで動く、もしくは mock を使ってテストできるフロントエンドに閉じるロジック
      • UI 操作、フロントでのバリデーションや、API の返り値を表示する部分などをテストします。
    • System Spec で書いた以外のバリエーションのテスト
      • API がエラーを返した際の挙動など、異常系のテストを行います。

やってみて実際どうだったか

Jest の導入により、system spec では細かすぎてなかなかテストしきれなかったボタンの制御やフォーム同士の相関的なバリデーションなどのフロントの挙動も確認することができるようになりました。これにより、プルリクエストごとに手動で確認していた部分が自動テストで確認できるようになり、テストコストの削減と品質向上を両立することができました。 既存の system spec の実行にかかる時間がまだまだ支配的なため、全体的なCIの実行時間を短縮するに至ってはいませんが、長期的な目線で見ると実行時間の増加は緩やかになっているはずです。 今後も品質と開発効率の向上のためテスト戦略の見直しと改善を続けていきたいと思います。

We are hiring!

大規模プロダクトの品質向上と開発効率の向上の両立に興味がある方、 SmartHRではエンジニアを大募集しています! 詳しくは以下のリンクをご覧ください。

https://hello-world.smarthr.co.jp/