フロントエンドエンジニアの 92thunder です。去年北海道旭川市に移住しまして、長らく打ち合わせを続けてきた家が10月にデプロイされたのでQoLが爆上がりしています。
テックタッチではデプロイ頻度を上げるためにテスト自動化に取り組んでいます。テスト自動化をQAエンジニアと進めていくためにテストの分類を策定する取り組みを始めました。この記事では、テックタッチにおけるフロントエンドのテストの分類とそれを策定するにあたって意識したポイントについて説明します。
デプロイ頻度改善のため、テスト自動化に取り組む
テックタッチでは新機能のリリース間隔は3ヶ月に1度となっています。リリースのプロセスについては、下記の記事でリリーストレインとして紹介しています。
テックタッチでは去年から、開発組織横断の開発プロセス改善するためのチームを立ち上げて、プロダクトのフィードバックサイクルの活性化に取り組んでいます。このチームの活動の1つとして、より素早くプロダクトの価値を顧客に届けるため、デプロイ頻度の向上に努めています。
テックタッチの開発においてデプロイ頻度を増やすための課題の1つとして、リリース前に実施するテストの工数が大きいというものがあります。これを解決するために、自動テストの割合を増やす活動に取り組んでおり、まずは QA チームとフロントエンドチームで自動テストへの認識を揃えるためテストの分類に取り組み始めました。
本記事で紹介しているフロントエンドのテストの分類だけでなく、自動テストを増やす開発プロセスを実現するための取り組みをまとめた発表資料があるので参考にしてもらえると嬉しいです。発表には自分の心の中で勝手に師匠として大リスペクトしている t-wada さんも聞きにきてくれて嬉しかったです。
フロントエンドエンジニアとQAエンジニアの協働による自動テストを増やす開発プロセス | ドクセル
なぜテストの分類が必要か
継続的にコスパの良い自動テストを増やすには、E2Eテストではなくユニットテストやインテグレーションテストといった実行やメンテナンスのコストの低いテストを拡充することが重要です。
E2Eテストでは、セットアップやビルドといったオーバーヘッドが発生する、テストケースも長い手順が必要となることが多く失敗しやすいといったデメリットがあります。テックタッチでも E2E テストを主軸とした自動テストは安定した稼働が難しかったという前例もありました。
QA エンジニアとフロントエンドエンジニアで実装した内容に対するテストを検討する際に、自動テストの分類が無ければ以下の理由によって E2E テストが多くなってしまいます。
- E2E テスト以外の自動テストでどんなテストが実行できるかわからないため、QA エンジニアから E2Eテスト以外のテストが選択肢として上がりにくい
- テストケース(テストの手順)を作成すると、手動テストを想定したE2E テストとなってしまう
QA エンジニアと共に、E2E テスト以外の自動テストを主軸としたテスト活動にしていくために、フロントエンドのテストの分類を策定することにしました。
テストの分類
テックタッチのフロントエンドで行なっているテストの分類を以下のように整理しました。
テストの分類 | テスト対象 | テスティングフレームワーク | バックエンドAPI |
---|---|---|---|
ユニットテスト | UI 依存が少ないロジック | Jest | モック |
コンポーネントテスト | UI コンポーネント(ロジックも含む) | Playwright Component Test | モック |
インテグレーションテスト | 複数成果物 | Playwright | モック |
E2Eテスト | 複数成果物 | Playwright | バックエンド実装 |
この分類は、QAエンジニアのメンバーにレビューしてもらいながら作成し、その後もワークショップによってそれぞれのテストでどんな手順や結果を確認できるようになるのかといったすり合わせを行うことで、QAエンジニアにE2Eテスト以外の自動テストへの理解を進めてもらうことができました。
今回作成した分類の中でもテックタッチのフロントエンド開発で特徴的なコンポーネントテストとインテグレーションテストについて説明します。
コンポーネントテスト
テックタッチのフロントエンド開発では、コンポーネントテストをメインのテストとして、機能追加時にはなるべくセットで追加するようにしています。コンポーネントテストは React、 TypeScript で作成したUIコンポーネントを対象に、Playwright Component Testを使ってテストを記述しています。UIコンポーネントの見た目だけでなく、振る舞いや内部のロジックについてもテストします。VRT(Visual Regression Test)も Playwright を活用した検証の1つの手段としてコンポーネントテストに含んでいます
Playwright Component Testを採用している理由は以下の3つです。
- テックタッチの開発に多いDOMに影響のあるコンポーネントのテストを実ブラウザ上で実行できるので信頼性が高い
- Test generator を活用して、ブラウザ上での操作からテストコードの作成やLocators(要素を特定するための情報)を取得することができる
- Headedモード や
page.pause()
を使うことで、UI上で実際の動作を確認できる - テストピラミッドやテスティングトロフィーに照らし合わせてコスパの良いテストを作ることができる
インテグレーションテスト
一般的にインテグレーションテストと聞いてイメージする分類とは異なり、このテストではSPAやブラウザ拡張といった実際にビルドされた成果物を対象にテストしています。テックタッチは顧客のWebページ上で動作するサービスであるため、自動テストによってリスクの大きい不具合をなるべく早期に発見できるようにしています。
外部要因の影響を受けずにフロントエンドの成果物を独立してテストできるように、バックエンド API は Playwright Mock API や MSW を使ってモック化しています。
このテストでは、ブラウザ拡張ならではの機能や、過去に障害として報告のあったような不具合が実際にビルドされた状態で再発していないことを検証することが多いです。以下はこの分類でのテストの例です。
- コンポーネントテストでは担保できない、ブラウザ拡張としてビルドされた状態でしか検証できない複数のタブを連携するような機能
- テックタッチによって意図しないプロトタイプ汚染が発生していないか
- 通信先を絞って動作するモードで、追加した変更によって意図しない通信先への API リクエストが発生していないか
- パフォーマンスを著しく低下させるような変更が発生していないか
テストの分類で意識したこと
フロントエンドだけでなく、QA エンジニアと連携しながら自動テストを増やす活動に使えるテスト分類を作るために意識したポイントを紹介します。
テストサイズを意識してコスパの良い自動テストへ
テストスコープを使った分類はチームや会社によってブレることが多いため、テストサイズを意識した分類にしました。テストスコープとテストサイズについては t-wada さんの資料で説明されているので参考にしてください。
それぞれのテストが、t-wada さん資料にある3x3分類のどこに該当しているか当てはめてみます。
Small | Medium | Large | |
---|---|---|---|
Unit | ユニットテスト(Jest) | ||
Integration | コンポーネントテスト(Playwright) | インテグレーションテスト(Playwright) | |
E2E | E2Eテスト(Playwright) |
テックタッチのフロントエンド開発時に Playwright によるコンポーネントテストを中心とした Small サイズのテストを書くことで、軽量な自動テストが多い状態を維持できると考えています。
また、Small サイズかつ Integration スコープのテストは、テストピラミッドやテスティングトロフィーとしても増やすべきテストだとされています。テストサイズによるテストピラミッドでは、忠実性は低いものの、コスト・速度・決定性のメリットがあるとしています。テスティングトロフィーでは信頼性とコストのバランスが優れているため、Integration テストを増やすことを推奨しています。
引用している図の参照資料
一般的な分類より、社内でのテストの呼び分けやすさを重視
世の中でいうユニットテストやインテグレーションテストの定義に合わせるよりも、自分たちで定義したわかりやすい分類によって、フロントエンドと QA チーム内で同じテストの分類を使って会話できることを優先しました。
テスト自動化といった DevOps の取り組みを始めるにあたって、共通の言語や定義を使って目線を合わせることを大事にしています。このあたりはドメイン駆動設計でいうところのユビキタス言語にも通ずる仕事の進め方ですね。
おわりに
テックタッチの開発にフィットするテスト自動化を進めていくための準備として QA エンジニアと対話しながらテストの分類を進めることができました。事業ドメインによって適したテストの分類があると思うので1つの例として参考にしてもらえると幸いです。
今回作ったテストの分類を活用して、自動テストを増やす取り組みに繋がっているので、他の取り組みについても別の記事で紹介したいと思います!