Peing*1でのにしさんへの質問で一瞬、テスト関連用語について議論が起きたので、自分の考えを整理しておきます。
質問の内容は、「期待結果」と「事後条件」の違いについてでした。 peing.net
これを見てのわたしのツイートは以下です。
一方、須原さんは以下のようなご意見でした。にしさんのコメントもぶら下がっています。
ISTQBの当初の意図は知らないけど、期待結果と事後条件はoutputかstateかで分けてるんだと思うんだよね。たとえば、赤色のLEDがつくこと、だったらoutputでもあるし、stateでもあるので両方に属する。stateは観測可能でない、が前提で。事後条件がテスト実装に使える、は結果論なのかなと。
— Hidetoshi SUHARA (@suhahide) 2019年12月9日
正直言って、須原さんのご意見のような観点では考えたこともなかったので、定義から読み直した次第です。
I/JSTQBの定義
まず基本に立ち戻って、ISTQBの定義の確認からしてみました。
期待結果(expected result)
The predicted observable behavior of a component or system executing under specified conditions, based on its specification or another source.
特定の条件下で、仕様や他の情報から期待できるコンポーネントやシステムの観測可能な振る舞い。
事後条件(postcondition)
The expected state of a test item and its environment at the end of test case execution.
テストケースの実行終了時に、テストアイテムやその環境が満たすべき状態。
いくつかキーワードがあるので、順に検討してみます。
観測可能
期待結果の定義にある「観測可能な振る舞い」という言葉は、大きなポイントになりそうです。
しかし、「観測可能でない」としたら、その事後条件が満たされていることをどのように確認すればいいのでしょうか。二つの考え方があると思います。
考え方1: 事後条件は確認すべき対象でない
確認すべきなのは期待結果であり、事後条件はそもそも確認しなくてもよい。あくまでもテストケースに対する付加的な情報である。という考え方です。
では何のためにそんな情報を明示するのか。それは「テストケースの接続」のためです。これについては後述。
考え方2: 事後条件は、当該テストレベルでは観測可能でない
原理的には観測可能だけれど、そのテストケースの位置づけ的には観測ができないという考え方です。
意味不明なので具体例で考えましょう。
こちらのサイトに、期待結果と事後条件の違いについての質問が載っています。
銀行の顧客が、ATMで口座からお金をおろすユースケースです。
BillThorさんの回答は以下のようになっています(意訳)。
- 事前条件: 顧客の口座には、おろす金額に対して十分な残高があること。
- 期待結果: 現金が引き出されること。
- 事後条件: 取引が記録され、顧客の残高はおろした分だけ減っていること。
テストでは、取引の記録も残高変化も「観測可能」でしょう。
ですが、システムテストレベルでユースケーステストを行う場合、視点はユーザであり、ユーザがデータベース上のレコードやログを「観測」することはない。「ログが出力されていること」はもっと前のテストレベルで確認済みのはずです。
このように、テストレベルやテストタイプに応じて、テスターの確認目的に合致するものが期待結果で、それより「内部」あるいは粒度の小さいものが事後条件と捉えることもできると思いました。
ふるまいと状態
ふるまいと状態は確かに別のものではありますが、「期待結果か事後条件か」を判断する際に有効な情報とは思えませんでした。
須原さんはブログ記事で、以下のように書いています。
やっぱりstateかそうでないかがカギですよね。期待結果として見られるものはなんらかのふるまいであり、もし状態が期待結果となるのであればそれは状態が結果としてふるまいになっているだけであると考えると区別はできそうです。
ふるまいの結果が状態になっているとしたら、そこに区別の必要性があるのか・・・がまだ咀嚼できていません。
テストケースの接続
テストケースが多数あると、それを効率的に実行していくために、テスト開始前とテスト終了後の状態を意識する必要があります。
これにも二つの考え方があるでしょう。
一つ目は、自動テストでよくいう setup / teardown です。テスト開始前と終了後の状態がいつも同じになるようにしておけば、テストの順番の重要性は薄れます。
もう一つは、「テストをつなげる」ことです。テストAの終わった状態と、テストBの始まる状態が一致していれば、テストAとBは続けて実行することができるわけです。たとえば、ログアウトのテストの後にログインのテストをするより、ログインしてからログアウトする方が自然でしょってことですね。
事後条件の定義に「環境」という言葉があるのもポイントです。
たとえば、「有線ネットワークが物理的に切断された場合のエラー処理」を確認したいテストケースがあるとします。この場合、テスト後には「ネットワークが物理的に切断されている」ことになりますが、これはテストで確認したいこととは関係がないので、期待結果ではなく事後条件に入るでしょう。
そしてこのテストケースの後に別のテストケースを接続したければ、「ネットワークが物理的に切断されている」ことを事前条件にもつテストケースを探してくるか、あるいはもっと単純に「ネットワークを物理的に接続する」作業が必要になります。
テスト対象のソフトウェアやテスト環境を含めたこれらの「状態」を形式的に記述できれば、最適なテスト実行プランを自動的に導くこともできるでしょう。*2
秋山さんの捉え方
秋山さんは、また違うことを教えてくださいました。
JSTQB的に言えば、テストで検証したいこと(=テスト条件)に対する検証エビデンスが期待結果です。
— あきやま🧌 (@akiyama924) 2019年12月9日
事後条件はカズさんのいう使い方もありますが、事前条件からの変化を書きます。
考えてみると、わたしはそもそも「事前」と「事後」を明確に対応させて記述していたかも怪しいです・・・。
まとめ
定義からいろいろ考えてはみたものの、特に正解を提示できるわけではないです。自分の意見をまとめておきたいだけ・・・。
ということでわたしの暫定的な理解を要約すると、以下。
- 期待結果と事後条件は、当該テストケースのテストレベルにおいて観測可能かどうかで区別する。
- 期待結果は、当該テストケースを pass にするための必要条件である。
- 事後条件は、当該テストケースを pass にするための十分条件であるが、pass / fail に関係のない情報も含まれる。
- 事前条件と事後条件を組み合わせることでテストケースを接続し、効率のよいテスト手順を提案することができる。