テストを実施する前に、まず各テスト工程の定義・粒度を明確にする。「単体テスト」「結合テスト」「総合テスト」「ユーザー受け入れテスト」などテストには幾つかの種類があり、テストの具体的なイメージは人によってまちまちである。「単体テストは関数やメソッドの単位でテストするのか」「それとも画面や帳票といった機能の単位でテストするのか」「あるいはユニットテストと単体テストに違いはあるのか」といったものだ。
定義が曖昧なままテストに突入すると担当者によってテストの粒度にバラ付きが出る。確認すべき観点が漏れ落ちて、後からテストをやり直すといった状況に陥りかねない。あるいは観点の重複もあり得る。単体テストで確認済みの観点を結合テストのテストケースにも盛り込んでしまうといったケースだ。この場合、貴重な時間や人手をムダにしてしまうことになる。
また、各テスト工程の定義・粒度はシステムの特性や規模によっても変化する。例えば、データ量が少ないシステムでは性能面を考慮する必要はほとんどない。一方、大量にデータを扱うシステムは処理のレスポンスを事細かに計測する必要がある。不要になったデータの削除も考慮すべきだ。また周辺システムが多い場合は、連携テストが重要だ。異常値も含めて緻密にテストしなければ、リリース後に障害が発生するだろう。
各テスト工程について、テスト仕様書作成期間、テスト実施期間、利用するツール、テストに関わる人とその責任範囲を設定するといいだろう。要件定義完了時点では、設計が煮詰まっていないため、テスト時間の見積もりや要員の予定を立てられないかもしれない。最初から100点の計画を立てるのは難しい。設計時にも継続してテストを考え、段階的に詳細化していくのである。
例えば次の図は、あるプロジェクトでのテスト計画でのテスト観点定義の表である。
一般的には総合テストで性能を検証するが、要求値を満たせない懸念がある箇所については早期に対策を講じる必要があるため、結合テストでも効率性の確認をするようにした。また、ユーザーの使い勝手(使用性)を重視していたため、結合テストの後に業務部門ユーザーによるレビューを行う「パイロット検証」工程を設けた。
このようにして、各テスト工程では「どの観点でテストをするのか」を俯瞰的に確認し、「漏れが発生していないか」「段階的に確認すべき項目がないか」などを考える。
具体的には、「性能面の問題が発生しそうな画面やバッチをピックアップし、どれぐらいのデータ量でテストするか」「どんなデータパターンを用意するか」「同時に複数のバッチを実行するか」といったテスト方法の“当たり”を付ける。
一つのテスト工程で全ての観点は網羅できない。各工程でパターンを網羅した完全無欠のテストを実施するには、工数がいくらあっても足りない。システムの特性を踏まえて、テスト工程と観点の組み合わせをしっかりと考えて、段階的に「品質」を作り上げるイメージを持ってほしい。
次に各テストの具体的なポイントを見ていこう。テストへの取り組み方は、目的・組織・文化によって考え方が異なる部分もあるだろうが、以下では筆者が考える各テストのポイントを示すので一つの参考にしてほしい。
単体テストではロジックの網羅に注力する。結合テスト以降では細かな確認はしないので、入力形式やエラーチェック、内部処理は全て確認しておく。ここで意見が分かれるのが「手法」である。「関数レベルでテストするのがよいか」「それとも画面や帳票といった機能単位が適切なのか」という対立がある。筆者の経験から言えば、後者の方が効率良く品質を担保できる。
というのも、関数レベルのテストは細か過ぎるからだ。関数そのものは正しく機能していても、機能全体の中で正しく役割を果たせていないケースは“まま”ある。関数レベルでの検証に注力するよりも、機能単体でテストした方が問題箇所を手っ取り早く把握できるのでムダがない。「関数レベルのテストが不要」と言っているわけではないが、あくまでも単体テストの主目的は機能単体で正しく動作するかにフォーカスすべきである。
動作の検証はホワイトボックステストとブラックボックステストに分けて考える。ホワイトボックステストは分岐や繰り返しといった内部の構造を踏まえたテストである。一方、ブラックボックステストは内部の構造を意識することなく、外部から見て仕様通りに動作することを検証する。
ホワイトボックステストでは分かりきったテストだけを実施する。例えば、レコードを日付検索する機能であれば、有効な値を入れて正しい値が返ることを確認する。テストケースが膨らむため、パターンの網羅性は追及しない。異常値はブラックボックステストで検証する。「閏日を入れる」「99月99日の異常値を入れる」といったパターンを盛り込み、エラー処理が正しく動作するかを確認する。
なお、ホワイトボックステストは極力自動化したい。検証データが決まっており、それに対応する入力値も決まっているからだ。例えば、Jenkinsを利用してテストデータをMySQLへ投入後、ドライバからのテスト実行の結果を確認するといった形で検証の手間を省くことができる。テストコードの管理も重要だ。製造時に作成し、テストを通過したモジュールのみマスターリポジトリへマージできるようにする。こうしたCI(Continuous Integration:継続的インテグレーション)はテストにおいてかなり有効な手段といえるだろう。
複数の機能を結合したときの動作を確認するのが結合テストである。これ以降のテストではパフォーマンスや使い勝手を確認する。この工程までに機能の「品質」を確保する。
結合テストには内部結合と外部結合がある。内部結合では1つのサブシステムが持つ複数の機能を結合したり、複数のサブシステムを結合したりして内部インタフェースを検証する。その後、他システムとの外部結合テストを実施する。結合対象を段階的に広げるのが定石だ。
単体テストでは単機能のロジックの網羅に着目したが、結合テストではデータのバリエーションを網羅するよう努める。ただし、発生し得る全パターンをテストするのは非効率だ。よって、出力が同じになるような入力をグルーピングし、グループの中から代表を選んでテストする「同値分割」の考えでパターンを絞り込むとよい。
総合テストでは、周辺システムなどとも接続してシステム全体を検証する。観点は機能だけでなく、性能やセキュリティ、システム運用なども含む。
機能の検証では、実際の業務と同様のシナリオを作成してテストを行う。しばしば議論に上るのは「テストシナリオの網羅性」である。筆者は必ずしも業務を全て網羅する必要はないと考えている。単体テストでロジックを網羅し、結合テストでデータのバリエーションを網羅しているからだ。そもそも、システム全体を通して網羅性を追求するのは作業量やテスト期間の観点で現実的ではない。
実際にシステムを利用する業務部門がシステム全体の動作を確認し、本番稼働させてよいかを判断するのがユーザー受け入れテスト工程である。総合テストの機能確認と同様、業務イベントをシナリオとして定義し、実際に業務をこなすイメージでテストする。
ユーザー受け入れテストでの確認点は二つある。一つは「要求通りにシステムが作られているか」、もう一つは「業務が回るか」である。「システムが要求通りに(=要件定義書通りに)動作しているので問題ない」と判断してしまいがちだが、そもそもの要求が間違っている場合もある。実際のシステムを利用し、業務が運用できるかどうかを業務担当者自身が最終確認する。
次は、品質分析にフォーカスを当てていく。
Copyright © ITmedia, Inc. All Rights Reserved.