「データ駆動テスト」についてのメモを書こうと思い立って、その前にまず「テストケースの構成要素」について整理しようと思って、そのためには「テストケースの期待結果と事前・事後条件」について考えをまとめなくてはならないと無限後退している鈴木です。
テストケースの構成要素
さあ、まずは「テストケースってどういうもの?」から始めてみましょう。
I/JSTQBの用語集では、テストケースは以下のように定義されています。
テストケース(test case)
Version 2
実行事前条件、入力値、アクション(適用可能な場合)、期待結果、および実行事後条件のセットであり、テスト条件に基づいて開発されたもの。
・・・あれ? なんかわたしの記憶では、構成要素は4つだったはず。
よく見ると、「Version 2」とあります。
そこで、URLハック(笑)して、Version 1の方を確認します。
テストケース(test case)
Version 1
入力値、実行事前条件、期待結果、そして、実行事後条件のセットで、特定のプログラムパスを用いることや特定の要件が満たされていることを検証することのような、特定の目的またはテスト条件のために開発されたもの。
やっぱり4つだ! バージョン1から2で、「アクション」、つまり「操作」相当の要素が任意で加わっているんですね。
これは直観に合う変更だと思います。「Enterボタンをクリックする」みたいな操作がテストケースに含まれない*1のには、どうも違和感があったので。
さらに、test stepという用語も定義されています*2。
テストステップ (test step)
Version 1
アクターとテスト対象の間の単一のやりとり。入力値、アクション、期待結果を含む。
絵にすると、こうなります。
「ステップ」と「アクション」は何となく同じ意味で使いそうだけれど、I/JSTQBの定義上は明確に違う用語であることに注意。この定義が絶対というわけではなく、曖昧な用語は定義合わせておいた方がいいよってことです。
なお、「誤解を招くテスト用語」の一角を占める「テスト手順」は、各テストケースがもつ情報ではなく、1個以上のテストケースをどの順番で実行するかを意味する用語です。
テスト手順(test procedure)
Version 1
複数のテストケースの実行順序。最初の事前条件や実行後の終了活動をセットアップするために必要な関連するアクションも含む。
期待結果と事前・事後条件
テストケースを書き下す際に、上述の構成要素をしっかり意識して書こうとすると、こんな悩みに突き当たります。
- 事前条件ってどこまで書くの? たとえば「サービスが起動していること」とか書くとキリがない。
- 事後条件と期待結果って何が違うの? 事後条件だって期待結果の一種ではないの?
この3つの要素について、以下の「ATMからお金を引き出す」例とともに考えていきましょう*3。
- ATMの電源が入っており、プログラムが起動しており、センターとの通信も確立されていることを確認する。
- ATMが待受け画面を表示している状態で、クレジットカードを入れる。
- 暗証番号入力画面で暗証番号を入力し、OKボタンを押す。
- メニュー画面で「現金引出し」ボタンを押す。
- 金額入力画面で引き出す金額10,000円を入力し、「OK」ボタンを押す。
- 現金10,000円が支払われ、終了画面に遷移して「ありがとうございました」と表示されることを確認する。
期待結果と事後条件
テストケースの構成要素のうち、テスト実行後に現れるものに、期待結果と事後条件の2種類があります。この2つはどう違うのでしょうか。
またぞろ定義を確認してみましょう。
期待結果(expected result)
Version 2
特定の条件下で、仕様や他の情報から期待できるコンポーネントやシステムの観測可能な振る舞い。事後条件(postcondition)
Version 2
テストケースの実行終了時に、テストアイテムやその環境が満たすべき状態。
ともに検証の対象になりますが、事後条件についてはポイントが2つあります。
- 期待結果と違って、観測可能であることが明示されていない。ユーザから観測可能とは限らない。
- 事前条件という対応要素がある。
この2つから、事後条件とは、「ユーザから観測できるかに関わらず、テスト実行前からの変化の有無を確認すべきもの」と考えることができます。
上述の例でいうと、画面(「待受け」→「終了」)が該当しそうです。ただより正確には、それぞれの画面に対応する「状態」があると考えるのがよいでしょう。この例での事後条件は、「終了状態であること」となります。
これ以外の「結果」を、期待結果とします。
この例でいうと、「10,000円が払い出されること」「終了画面が表示されること」がわかりやすい期待結果です。「5秒以内に払い出されること」といった非機能要件や、「適切な紙幣の組み合わせで払い出されること」といった暗黙の期待値も含まれるでしょう。
事前条件と前提条件
事前条件は、事後条件から逆算することができます。今回の例では、事後条件「終了状態」に対して、「待受け状態」というのが事前条件となります。
事前条件と事後条件は、必ずしも別のものであるとは限りません。「変化していないこと」を確認したい場合は、それも事前・事後条件に含めておきます。
さて、では、「ATMの電源が入っている」などはどこに行くのでしょうか。
事前条件の定義はこうなっています。
事前条件(precondition)
テストケースの実行前に、テストアイテムやその環境が満たすべき状態。
ですので、「ATMの電源が入っている」も事前条件と捉えてもいいでしょう。
ただ今回の例では、「ATMの電源の状態」はテストの意図とまったく関係がありません。「満たしていないとテストができない」というだけです。こういったものは、「前提条件」として分けた方が、テストの意図が明確になるように思います*4。
前提条件は、網羅的に書き下す必要はありません。ATMの機能を確認するのに、「ATMの電源が入っている」はあまりに自明なので、書かなくてもいいでしょう。一方で、預金引き出しのテストをする際に「十分な現金がATM内にあること」は書いておく方がいいかもしれません。
テスト構成要素の仕分け手順
以下、サマリです。
- まず、テスト実行後に確認したい項目を洗い出す。
- 1.のうち、テスト実行前からの変化の有無を確認したい項目を「事後条件」とする。
- 1.のうち、2.に残らなかったものを「期待結果」とする。
- 2.で選んだ「事後条件」に対応するものを「事前条件」とする。
- 4.以外に整えておくべき条件を、「前提条件」とする。
事前条件・事後条件の役割
事前条件と事後条件の役割を3つ、整理しておきましょう。
役割1: テスト実行前に整えるべき条件を明確にする
これは自明ですね。事前条件(と前提条件)を整えることで、テスト実行が可能になります。
役割2: テスト前後で確認すべき変化を明確にする
テスト実行後の確認内容がわかります。
役割3: 別のテストケースとの連結可能性を明確にする
これは、今回の議論に出てこなかったものです。
あるテストケース①の事後条件が、別のテストケース②の事前条件と一致していれば、①と②を連続して実行することができます。これによって、2つのテストを独立に準備して実行するよりも効率的に実行できる可能性があります。状態遷移テストなどはわかりやすい例でしょう。
まとめ
今回の議論をまとめた結果が、以下の絵です。
おわりに
いつも気軽に定義を引用していますが、ISTQB Glossaryが無償で公開されていること、これはQA・テストに関わる人には本当にありがたいことですよね。用語や概念を整理してくれた方、用語集を作った方、Webサイトにしてくれた方、感謝を忘れないようにしたいと思います。