今回は 「プロダクト開発におけるテスト設計」 についてお話します。
- テストはどこまでやれば良いのか分からない
- そもそもどんなテストをすれば良いのか分からない
- 効率よく品質を担保したいけれど、自社のテストの網羅性が分からない
ほぼ全ての会社で開発時にテストは実施されているものの、独自のやり方でテストをしていて、 「本当にこのやり方で良いのか?」と考えたことはありませんか?
今回は一つの事例として、弊社で実際に実施しているテスト設計についてお話します。
今回は 「プロダクト開発におけるテスト設計」 についてお話します。
ほぼ全ての会社で開発時にテストは実施されているものの、独自のやり方でテストをしていて、 「本当にこのやり方で良いのか?」と考えたことはありませんか?
今回は一つの事例として、弊社で実際に実施しているテスト設計についてお話します。
この記事のサマリー
テストは何のために実施するのでしょうか?開発速度を上げるため?バグを出さないため?
そもそもプロダクト開発は、 「売上を増やし、コストを削減することで利益を最大化させる」 ことを一義的な目的としてしています。
プロダクト開発のテストはこの目的を達成するための一つの手段に過ぎません。 よって、プロダクト開発のテストでは 「事業の利益を最大化する為の必要最低限のテストを実施する」 というのが基本戦略になります。
きちんと設計せずにテストを実施していくと、上図、左の絵のような 「アイスクリームコーンアンチパターン」 になってしまいます。
画面を手動で操作して、一度にすべてを確認すると一見効率が良いように見えますが、実際には不安定なテストな為、ランニングコストが増えていく構造になってしまいます。
テスト設計時に大切なのは小さいテストを積み上げて、上図にある右の絵のような 「テストピラミッド」 になるようにテストを設計していく必要があります。
プロダクト開発におけるテストには様々な目的のテストがあります。
その中でも代表的な8つのテストをご紹介します。
単体テストは 「メソッド単位やクラス単位のテスト」 のことを指し、主に 「リファクタリングのしやすさ担保 + 内部結合(コンポーネント)テストで担保しづらい観点を担保」 することを目的としているテストです。
主に開発者が担当するテストになります。ただし、あまり多くのテストが書かれるものではありません。このレイヤーのテストを増やしてしまうと、コードの書き方に依存したテストが増えることになり、リファクタリング時に不要な修正コストがかかってしまいます。
小さすぎるテストは時としてデメリットになることを認識しておくことが大切です。
内部結合(コンポーネント)テストは 「API単位やページ単位のテスト」 のことを指し、主に 「機能要件担保」 することを目的としているテストです。
システムの品質を担保する際に、最も重要になるテスト です。各システムコンポーネントごとに機能要件をブラックボックステストで担保していくことになります。
このレイヤーのテストをどれだけ自動化出来るかがシステムの品質に直結する ことになります。
効率良く内部結合結合テストを実施する為に、ソースコードの技術基盤では、適切に外部コンポーネントを隠蔽化し、テストデータの準備を容易にする設計にしておくことが大切です。
基本的に、このレイヤーのテストまではマニュアルテストで担保するような事はないと思います。
外部結合テストは 「システムコンポーネントを跨るテスト」 のことを指し、主に 「ネットワークやIF等の通信担保」 することを目的としているテストです。
このレイヤーのテストではマニュアルテストと自動テストを目的に応じて選択する必要があります。 システムもチームも小さい内は、ローカルで実際に結合しながら開発するでしょう。その場合には取り立てて外部結合テストの自動化をしなくても良いかと思います。
チームやサービスがスケールしたタイミングであっても状況によっては、自動テスト実装まで行かないケースもあります。
以下、外部結合テストの観点を担保する手法とそのタイミングについて表にまとめました。
手法 | 選択理由 |
---|---|
IF仕様書 | チーム内外でAPIのインターフェイスの形式知化が必要な場合はOpenAPI準拠のIF仕様書を作成し、形式知化によるコミュニケーションを図ることで品質を担保することができます。 |
コントラクトテスト | 規模が大きく複数のチームで開発を推進していて、IFの担保を自動化したい場合はコントラクトテストを自動化することを検討します。ただし、CI/CD構築コストやコントラクトファイルの管理コストが増えるので、チームの規模に応じた費用対効果の検証は必要になります。 |
E2Eテスト | UIレベルやAPI単位での外部結合テストを自動化したい場合に検討されます。ただし、UIレベルからの外部結合テストを自動化する場合はテストのメンテナンスコストが高いので、費用対効果の高いケース(よく使われる機能など)にのみ適用することをオススメします。 |
シナリオテストは 「ユーザーストーリー単位でのテスト」 のことを指し、主に 「データのライフサイクル担保」 することを目的としているテストです。
これより以前のテストが適切に設計されていれば、想定されるユーザーストーリーを通した後に、最終的に生成されるデータが問題ないことを確認してください。
UX/UIテストは 「プロダクト全体を通したテスト」 のことを指し、主に 「ユーザー体験担保」 することを目的としているテストです。
デザイナーやCSにユーザー目線の操作性についてフィードバックをもらうことで、プロダクトのUX/UIの品質を向上させることができます。
結合テスト時のみではなく、コーディングの途中でもこまめにコミュニケーションしながらUX/UIを確認していくことで、価値の高いプロダクトを開発することができます。
受け入れテストは 「プロダクト全体を通したテスト」 のことを指し、主に 「ビジネス観点での要件担保」 することを目的としているテストです。
プロダクトマネージャーやディレクターなど、要求を出した人に__目的を達成できる機能になっているか__ を確認してもらうテストになります。
基本的には、これより以前にコミュニケーションをしながら開発していくと思うので、大きな齟齬が生まれるケースは少ないですが、念の為、要求を出した人にリリース前に確認してもらうことをオススメしています。
受け入れテストは 「画面単位やAPI単位など様々」 のことを指し、主に 「速度やSLA担保」 することを目的としているテストです。
新しいシステムコンポーネントが増えた場合や重たい処理が追加された場合に実施されるテストになります。
サーバーのスペックを調整しながら、スループットやレイテンシなどを計測し、サービスが落ちないようにインフラ設計をしていきます。
受け入れテストは 「プロダクト全体を通したテスト」 のことを指し、主に 「セキュリティ面を担保」 することを目的としているテストです。
新しいサービスをリリースする際に実施すると良いでしょう。一般的にはセキュリティチェック会社に委託するケースが多いように思います。
テストは闇雲に実装すれば良いものでもありません。
適切にレイヤーを分けて、マニュアルテストと自動テストを上手く使い分けながら、「事業の利益を最大化する為の必要最低限のテストを実施すること」を達成してください。