ソフトウェアを開発するときは、テストケースが重要になってきます。この記事をお読みの方はまさに今、テストケースの設計にお悩みかもしれません。私はこれまでウェブエンジニアとしてソフトウェアの開発に携わってきました。この経験をもとに、テストケースとは何か、作り方や書き方、項目の洗い出しについて解説します。
この記事は、ソフトウェアのテストケースを設計する方、特にテストケースの設計経験が少ない方を対象としています。また、私はウェブエンジニアなので、その文脈でまとめています。テストケースを設計するときの参考になればうれしいです。
テクニカルライター。元エンジニア。共著で「現場で使えるRuby on Rails 5」を書きました。プログラミング教室を作るのが目標です。
テストケースとは
まず、テストケースとは何か?ということについて整理します。テストケースとは、「ソフトウェアをテストする方法を記述した手順書」のことをいいます。このテストケースをもとに、手動でテストを行ったり、あるいは自動テストを実装したりします。
まずはじめに、この記事の前提知識として「テストの種類」と「テストケースの種類」について説明します。なお、テストケースについてより詳しく学びたいときは、「ソフトウェアテスト技法練習帳」という本があります。ソフトウェアテストの知識を定着させることを目的とした本になります。あわせてご覧ください。
テストの種類
ひとことでテストといっても、ソフトウェアのテストにはいろんな種類があります。例えば、代表的なものの中に次の3つがあります。
種類 | 説明 |
---|---|
ユニットテスト | モジュールのメソッド単体に対するテスト |
インテグレーションテスト | モジュール間の連携に対するテスト |
システムテスト | ユーザー視点でのインターフェースを通したテスト |
テストケースの種類
また、ソフトウェアをテストする方法を示すテストケースには、正常系と異常系という2つの種類があります。
種類 | 説明 |
---|---|
正常系 | 想定している入力に対して、期待通りの出力を行うか |
異常系 | 想定していない入力に対して、問題なく対処できるか |
以上をまとめると、ユニットテストなどのいろんな種類のテストについて、正常系と異常系をもとにテストの手順を書いていくのがテストケース、ということになります。
なぜテストケースを作るのか
そもそも、なぜテストケースを作る必要があるのでしょうか?テストケースの設計に初めて携わる方は、その必要性が分かりづらいかもしれません。
テストケースは、「それをもとにテストを行う」という手順書になるのはもちろんそうなのですが、品質という意味でも次の3つの目的があります。
- 必要なテストを漏れなく実施するため
- 不要なテストを削除するため
- 誰が行っても同じテストにするため
この3つについて説明します。
1. 必要なテストを漏れなく実施するため
ソフトウェアが正しく動作するかどうかは、テストを通して確認します。言い換えると、テストケースが足りない場合、ソフトウェアが正しく動作しないかもしれません。例えばバグがあると、ソフトウェアは正しく動作しません。
このようなテストの漏れは、テストケースを書くことでいくらか解消できます。テストケースがあることで、いろんなメンバーからレビューを受けることができるため、必要なテストケースがあるかどうか?という確認をすることができます。
例えば、あなたが入ったばかりのプロジェクトのテストケース作成を担当することになったとします。この場合、あなたはシステムやビジネスに詳しいとは限りません。つまり、作ったテストケースに漏れがある可能性があります。
こんなときに、システムやビジネスに詳しいメンバーからのレビューを受けることで、不足したテストケースを追加することができます。
システムのすべてのバグを防ぐことは難しいですが、減らすことはできます。リリース後に見つかるバグの修正コストは大きくなりがちなので、その意味でも、テストケースをしっかりと作る必要があります。
2. 不要なテストを削除するため
必要なテストが漏れるのはよくないことですが、一方で漏れのないテストにしよう!と考えて、テストケースを無駄にふやしがちになる、という問題もあります。
テストケースは多すぎてもよくありません。テストを行うことはコストになりますし、テストケースを維持するのにも同じくコストがかかります。そもそも同じ目的のテストケースがいくつあっても、品質の向上にはつながりません。
テストに詳しいメンバーからのレビューを通して、不要なテストケースを削除することで、将来的なコスト削減などにつながります。
3. 誰が行っても同じテストにするため
テストを手動で行う場合、テストを行う人の能力によってシステムの品質に差が出てしまってはいけません。自動テストにおいても、同じく実装者によって差が出てしまわないようにする必要があります。
テストケースを作ってレビューを行うことで、テストの品質を高い水準に保つことができるようになります。
テストケースの作り方
それでは、本題であるテストケースの作り方について説明していきます。テストの種類としてはユニットテストやシステムテストなどいろいろなものがあると説明しましたが、テストケースの基本的な作り方は次のようになります。
順番 | 項目 | 内容 |
---|---|---|
1 | 前提条件 | テスト対象の前提となる値や状態はなにか |
2 | 手順 | どのようにテストするか |
3 | 入力値 | どのような値を入力するか |
4 | 期待する結果 | どのような結果を期待しているか |
この表だけだと分かりづらいので、具体的な例を見てみます。
テストケースの例
例えば、分かりやすい例として「一桁の自然数同士のかけ算をする計算機能」のテストケースについて考えてみます。一桁の自然数とはつまり1〜9の値を取りうるのですが、この場合は次のようなテストケースができます。
項目 | 内容 |
---|---|
前提条件 | 5が入力されている |
手順 | かけるボタンを押す |
入力値を押す | |
計算ボタンを押す | |
入力値 | 6 |
期待する結果 | 30が表示されている |
このような表が、テストケースのひとつの例になります。
テストケースの入力値
前述したテストケースの例は、必要なテストケースのひとつでしかありません。実際には、一桁の自然数同士のかけ算、つまり1〜9同士の掛け算になるので、全部で81通りの組み合わせが考えられます。
また、入力可能性という意味では無限にあり得ます。どういうことかというと、不正な入力として0や-1などが入力される可能性も考慮しなければなりません。
この組み合わせについて、すべてのケースをテストするのは大変で、コストもかかります。このようにテストケースが多いときに、品質を保ちつつケースを減らす方法として、次の4つがあります。
- 同値分割
- 境界値分析
- ペアワイズ法
- エラー推測
それぞれについて説明します。
1. 同値分割
同値分割とは、入力をグループ化して、有効なものと無効なものに分けるやり方です。例えば「一桁の自然数」が入力だとすると、次の3つのグループに分けることができます。
- 1より小さい
- 1〜9
- 9より大きい
つまり入力値として、例えば0と、5、10の3つにすればよい、ということになります。これが同値分割です。
2. 境界値分析
同値分割において、経験則的に「同値グループ間の境界にバグが発生しやすい」ということが分かっています。どういうことかというと、同値分割で示した例でいう0と1、9と10などの値を入力したときに、バグが発生しやすくなります。
このような境界値では、等号や不等号のミスなどでバグが起きやすくなるのですが、これを境界値分析で検出することができます。
3. ペアワイズ法
ペアワイズ法とは、「ほとんどの不具合は1つまたは2つの要因によるものである」という経験則をもとにした方法で、たくさんある要因のうち「2つの要因の組み合わせだけは網羅する」、という観点で値を選ぶ方法です。
例えば、前述した計算機能の例では、要因は「前提条件」と「入力値」の2つですが、テストの対象によっては要因がもっと多くなることもあります。このとき、すべての要因についてテストを実施するのは大変ですが、ペアワイズ方を用いることで、テストを大きく削ることができます。
一方で、ペアワイズ法では本来検出できたはずのバグを取りこぼす可能性もあります。ペアワイズ法だけでテストせずに、組み合わせを選ぶときの参考にする程度でいいのかな、と思います。
ペアワイズ法により組み合わせを選ぶ方法として、マイクロソフト社製のPICTというツールがあります。
4. エラー推測
これは上の3つの方法論とはちょっと変わっているのですが、「テストケースを作る人の経験に基づいて、エラーが起きそうな値を決めるやり方」です。例えば「一桁の自然数」という入力値に対して、負の数やヌル文字、空白、全角文字や小数などを用いてテストします。
テストケースの観点
ここまでで、テストケースの作り方と、入力値の選び方について説明しました。最後に、テストケースを作るときの観点をいくつかあげてみます。テスト対象となるシステムによって違うと思いますが、テストケースを設計するときの参考になればと思います。
全般
- 入力に対する結果は正しいか
- 想定していない入力に対処できるか
- 入力の型や文字コードの種類は想定されているか
- 不適切な入力は想定されているか
- リクエストに対するレスポンスは正しいか
データ
- レコードは正しく更新されているか
- トランザクションは考慮されているか
セキュリティ
- 脆弱性は考えられないか
- 認証、認可のロジックは問題ないか
- 認証、認可失敗時の動作は問題ないか
エラー
- エラー処理はされているか
- 例外処理はされているか
画面
- データがないときの処理・表示は問題ないか
- 文言は正しいか
- 画面の遷移先は正しいか
アクセス
- 多重実行は考慮されているか
- 遅いネットワーク環境での利用は考慮されているか
- 処理がキャンセルされた場合は考慮されているか
- 同時アクセスは考慮されているか
- 同一ユーザーの複数端末からの利用は想定されているか
- 利用環境の差異(OSやブラウザなど)は想定されているか
- 利用者の役割(ゲスト、管理者など)は考慮されているか
環境
- 実行環境の差異(開発環境、本番環境など)は想定されているか
- 時間やタイムゾーンの問題はないか
通信
- APIなどの通信先は正しいか
- APIなど通信先のステータスは考慮されているか
- 非同期処理のタイミングによるデータの有無は考慮されているか
- 非同期処理は必要なところでされているか
- メールやチャットなどへの通知は行われているか、送り先は正しいか
いつテストケースを作るか
ここからは余談になりますが、次にテストケースを作るタイミングについて説明します。特に決まりはないですが、テストケースは、そのテストの対象となる機能が入るタイミングで作成したりします。
例えばアジャイル開発においては、継続的にソフトウェアを変更するので、最初からすべてのテストケースを作ることはないと思います。ソフトウェアを変更するときに、変更とあわせてテストケースを追加したりします。
具体的な例として、GitHubのプルリクエストを通してソフトウェアを変更している場合は、プルリクエストの本文にテストケースを書き、ソースコードとあわせてレビューすればいいと思います。
読み手のことを考える
また重要な点として、テストケースは手順書なので、読み手がいる、ということになります。作成した本人には理解できても、テストを実施したりテストコードを実装する人には分かりづらいかもしれません。
読み手が分かるような文章にすることを心がけて書いていきましょう。
まとめ
この記事では、テストケースとは何か、作り方、項目の洗い出し方などについて説明しました。システムやビジネスの種類によって書くべきテストも変わってくるので、目的に合わせてテストケースを作れるようになれたらと思います。