本コラムはテスト分析手法「ゆもつよメソッド」で有名な湯本 剛氏(freee株式会社/株式会社ytte Lab)による連載コンテンツです。
湯本氏のnote「テストマネジメント虎の巻」はこちら
本連載では、ソフトウェアテストをする際には、ビジネスの成功に貢献するという本来の目的を意識しながら、これからの開発に役立つことを考えていくことが重要だと説明してきました。考えていくべきことは、以下の4つになります。
- 開発チームとテストチームの関係
- 品質リスクの許容度合い
- テストレベル間のテスト量の関係
- QA(Quality Assurance)の考え方
前回は、品質リスクの許容度合いについて詳しく説明していきました。今回は「テストレベル間のテスト量の関係」についてです。まずは、テストレベルについておさらいし、ビジネスの成功に貢献するにはどうすべきかについて述べます。
1.テストレベルとは何か
テストと開発の関係を表したV字モデルをご存知でしょうか。テストレベルは、V字モデルで表現されている、開発の段階的詳細化(要件定義、基本設計、詳細設計、実装)と対になるテストプロセスです。いわゆる、ユニットテスト、インテグレーションテスト、システムテスト、システムインテグレーションテストがテストレベルに該当します。
各テストレベルは、異なるテストレベルの中でテスト実行のやり方、テスト環境、テストデータのどれかが一緒になることがあります。テストレベルを分ける際に明確に区別すべきはテスト対象です。ユニットテストは関数やメソッド、機能単体テストであれば画面やバッチ、インテグレーションテストであればI/F、システムテストでは業務フローといったように、テストアイテムをどういう切り口で見るかを明確に分けます。そのため、テストベースも異なります。ユニットテストはメソッドレベルの設計書、もしくはそれに相当するものであり、システムインテグレーションテストは業務レベルの記載がある要件定義書、もしくはそれに相当するものになります。これらは典型的な例であり、開発の仕方やアーキテクチャーに依存します。
2.テストレベルを設定する理由
V字モデルのようにテストレベルを設定してテストをする理由は、開発したものに対してより早くテストを始めて、プロダクトリスクを早く軽減するためです。コーディングした直後であれば、開発者はコードを理解した状態でテストするので、欠陥を見つけた後のデバッグに時間はかからないでしょう。コーディングした後、1ヶ月以上たってからデバッグするとなると、それがたとえ自分で書いたコードだとしても、どういう仕組みで動いていたのかが分からなくなってしまう可能性が高くなります。
例えば、プログラムが複雑になる前に、メソッドレベルの問題を解決しておくことによって安心してクラスを統合させて実現する機能のテストができるはずです。これが何もテストしていないクラス同士を統合させたとなると、欠陥の原因の特定をするための選択肢が増えてしまい、テストにもデバッグにも時間がかかってしまいます。
また、本番リリース間近にパフォーマンス遅延に問題が見つかったとします。デバッグした結果、データを取得するためのSQL文がとてつもなく長くなってしまうデータベースのテーブル構造が原因だとしたら、そのような問題はもっと早めに解決しておくべきです。本番リリース直前にテーブル構造を変えるとデグレードのリスクが高まってしまいます。
3.テストピラミッド
V字モデルでは、各テストレベルでどの程度テストをするべきかを定義していません。各テストレベルにおけるテスト量を明示的にしたモデルにテストピラミッドがあります。JSTQBのアジャイルテストシラバス[1]では、テストピラミッドについて次のように書かれています。「低いレベル(ピラミッドの底部)ほど多くのテストが存在し、開発が上位のレベル(ピラミッドの頂点)に進むに従って、テストの件数が減少することを表す。通常、ユニットレベルと統合レベルのテストは自動化し、APIベースのツールを使用して作成する。システムレベルと受け入れレベルでは、GUI ベースのツールを使用して自動テストを作成する。テストピラミッドのコンセプトは、早期にQA とテストを開始するというテストの原則に基づく(欠陥をライフサイクルの中で可能な限り早期に削減する)。」
手動テストであっても自動テストであっても各テストレベルで行うべきテストを行い、後続するテストレベルにて前段階のテストレベルで見つかる欠陥が出ないようにすることが重要であることに変わりはありません。
ただし、アジャイルのような開発スタイルにて、開発がある程度完了してからユニットテスト、インテグレーションテスト、システムテストをそれぞれ順番に行うテストアプローチをとると、テスト工程だけ時間がかかる、つまり開発スピードを妨げる原因になります。開発スピードが落ちてしまうと、この連載で何度も書いているトライアルアンドエラーの妨げになります。テストピラミッドは、もともと自動テストをどう組み立てるか考えるためのモデルですが、テストが開発の妨げにならないためには、自動テストだけに限らず、手動テストも含めてテストピラミッドのモデルのようなテスト量のバランスを保つアプローチを実践していく必要があります。そのためにはどのようなアプローチがあるか、いくつか例を挙げていきます。
[1]テスト技術者資格制度Foundation Level Extension シラバス アジャイルテスト担当者 日本語版 Version 2014.J01(http://jstqb.jp/syllabus.html#syllabus_foundation)
4.ユニットテストを成長させる
本連載の2回目、3回目で言及した、リグレッションテストが主役になる昨今の開発スタイルでは、一度開発したコードに修正が入ることが増えるため、ユニットテストを何度も実行することが求められています。テストピラミッドの説明にて「ピラミッドの底部ほど多くのテストが存在」と書いてあるのは単にテスト量が多いだけでなく、実行回数が多いことも含まれています。繰り返し実行するためにはユニットテストの自動化が重要になります。
ユニットテストを実行した際には、常にコードカバレッジを計測してテストできてない部分がないかを確認します。コードの変更によりカバー範囲が変動するためです。そして、常に計測結果を確認するためには、計測や結果確認のレポートも自動でできるようにします。カバー範囲を保つためにテストを追加する際は、QAメンバーが実行している手動テスト用のテストケースを参考にする事例も多くみられます。このようにユニットテストを成長させて、ユニットテストのレベルでリグレッションテストを常に行うことは、将来の変更に向けた欠陥予防になります。
5.システムテストは早い段階から少しずつ行う
1週間や2週間といった単位で開発をすすめていくと、その期間内に機能が100%完全に実装できていないことがあります。その場合でも、システムテストとして確認できる部分があれば、完全でなくてもテストを実行します。それによって、すべて実装完了した後から一気にテストをするビッグバンテストを行わないで済みます。ビッグバンテストは短期間に多くのテストケースを実行するため、以下のように多くの弊害がでてきます。
- ビッグバンテストのために途中から参画するメンバーは、テスト対象を理解する時間もあまり取れないままテストをすることになります。
- そのメンバーの理解不足を補うような準備をするための工数が必要になります。
- 欠陥の発見と修正が一時期に集中するため、デバッグにかかりっきりになってしまいます。
ビッグバンテストを予防するためには、できるだけ早い段階からシステムテストを行うのが得策です。開発チームの中にテストの専任者がいると早い段階からシステムテストを行いやすくなります。
また、システムテストの自動化にてユニットテストの自動化のようにテストを網羅的に行うのは、パターン数が増えるため困難です。また自動化を保守する工数もユニットテストよりかかります。システムテストの自動化は、一度手動でテストしたテストケースのうち、繰り返しテストをすると効果的で、単純な手順で繰り返せる箇所を選んで局所的に行うようにします。
6.曖昧な仕様をなくしていく
開発の最初の時期からテスト担当者がチームにいると、早い段階からシステムテスト用のテスト設計を始めることができます。その際、テスト設計の際に出てきた仕様に対する疑問点をチームへフィードバックすることで、曖昧な仕様を明らかにできます。また、前述したシステムテストを早い段階から少しずつ行うことでも曖昧な仕様を明らかにできます。そして、システムとして動作させることは、妥当性の観点での気づきを得ることもできます。
ここで大事なのは、チームメンバー全員がテスト対象に対して同じ程度の理解があり、対等な関係でフィードバックができるようにすることです。このような活動を通してチーム全員の仕様に対する理解度を向上させていくことは、仕様が曖昧なまま実装してしまうことを予防することになります。
おわりに
今回は、「テストレベル間のテスト量の関係」について深掘りをしていきました。
これからの開発はトライアルアンドエラーが大事であり、そのためには、テストピラミッドのような低いレベルのテストを増やし、開発の後半のテストをできる限り少なくするようなテストアプローチを実践することが重要になります。
次回は最終回になります。最終回は「QA(Quality Assurance)の考え方」について深掘りしていきます。