単体テストの効率化を考える(8)
単体テスト設計書

どもです。

今回も「テストドライバの実装の効効率化による単体テストの効率化」について考えていきます。
前回のエントリの最後に書いた通り、今回は「どのような設計書を作るか」について書きます。

1.単体テストの設計書のあるべき姿

個人的には、(単体テストに限らず)テストの設計書の「あるべき姿」は以下であると考えています。

  • テストケースを作成するために必要な値が記載されている
    • 具体的な入力値が明確に記載されている
    • 具体的な期待する結果が明確に記載されている
  • テストの観点や目的を読み取ることができる

「テストケースを作成するために必要な値が記載されている」については、設計書に具体的な値が記載されていない場合、テスト実施者ごとに入力値が異なる可能性があります。
「入力値が異なっていたとしても、テストができていればOKだ」と考える方もいると思います。
この考えについては、私も同意します。
しかし、具体的な値が書かれていない場合は、テストを実施するタイミングで入力値を考えなければならず、効率が悪いです。

2.具体的な単体テスト設計書

単体テストの設計書のあるべき姿を、具体例を示しながら考えます。

2.1.テスト対象の具体例

テスト対象の具体例として、以下の処理を行う関数を考えます。

  • 2つの入力が示す点が、2次元グラフのどの象限にいるかを返す。
  • 2つの入力が原点であった場合、第1象限とする。

この処理のフローチャートは、下図のようにできます。

2.2.単体テストの設計技法

単体テスト設計の有名の技法として、「デシジョンテーブル」があります。
今回も、この技法を用いてテスト設計、テスト設計書を作成してみます。
デシジョンテーブルの詳細については、様々な書籍・サイトで紹介されています。
そのため、本エントリでは詳細な説明は割愛しますので、各自で調べてください。
ココでは、簡単な説明のみに止めます。
デシジョンテーブルとは、

入力条件とその入力による動作を表形式で表現し、テストケースを作成する手法。

です。
今回の場合、「入力条件」が「2つの入力」になり、「その入力」が「2つの入力」の具体的な値になります。
まず、入力条件のみに着目して作成したデシジョンテーブルが、下図になります。

この図での条件「A」と「B」は、下図のフローチャートに示す条件に対応します。

この図から、「入力条件」の組み合わせについては網羅できていることが分かります。
しかし、具体的な「入力」については分かりません。
そこで次に、具体的な「入力」を明らかにしていくために、各条件の判定内容を追記してみます。
追記した結果が、下図になります。

この図では、T/Fがたくさん表示されており、それぞれの列でどのパターンの組み合わせを行っているかが分かりにくいです。
なので、T/Fではなく、適用している条件の行に「A」を記入し、適用指していない条件の行は空欄にしてみます。
その結果が、下図です。

少し見易くなりました。
次に、表内の「判定内容」を満たす「入力」を、具体的に考え決定します。
「入力」を考える際には、「同値分割」「境界値分析」という手法を適用します。
「同値分割」とは、

処理の実行結果をグループ分けし、その結果をもたらす入力を全て同じグループ(同値クラスと呼ぶ)に振り分ける手法。

です。
境界値分析は、

  • 同値分割の拡張
  • 同値クラスの最小値および最大値を見極める手法

です。
多くの場合、これらの手法により明確になった「境界値」と、+1/-1した値をテストの入力とします。
今回の例では、「境界値」は「0」になりますので、この値と「+1」、「-1」した値がテストの入力になります。
これを先ほどのデシジョンテーブルに記入した結果が、下図です。

なお、テストの入力となる値(「0」、「1」、「-1」)は特に「代表値」と呼びます。
ここまでで、デシジョンテーブルに具体的な「入力」が明記され、テストを実施する際に入力しなければならない値が明確になりました。
最後に、各代表値を設定する先を「代表名」として記入します。

なおこの「代表名」は、私のオリジナルです。
もっと別の名前でも問題ありません。
今回の例では、「引数」が入力になりますので、そのまま「引数」と書いても良いです。

3.まとめ

今回は、デシジョンテーブルを用いたテスト設計について書きました。
同値分割、境界値分析を用いることで、関数へ入力する具体的な値、そして期待値が明確になっているデシジョンテーブルが作成できました。
また作成したデシジョンテーブルでは、「条件」の内容を確認することで、その観点/目的が確認できます(たぶん…。いやきっと!)。

さて。
これでテスト設計ができました。
そこで次回は、今回作成したデシジョンテーブルの内容をテストドライバに実装してみます。

ではっ!