Index: [Article Count Order] [Thread]

Date:  Thu, 7 Dec 2000 13:47:33 +0900
From:  firo <firo@....jp>
Subject:  [XP-jp:01265] Re: テストはテスト ?
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <00Dec7.135115jst.115203@....jp>
References:  <000001c05f4b$1f6d0c00$010400c8@Ra20>
Posted:  Thu, 7 Dec 2000 13:51:12 +0900
X-Mail-Count: 01265

矢崎です。

Ootaさん wrote:

>  私もこの点が気になってJPLoPの友野さんにお聞きしたのですが、XPでいう
> テストはMeyerの契約主導設計の実現の一種であるというお話でした。「表
> 明」というのでしょうか。「表明」は「こうなっているべきだ」というのを事
> 前条件、事後条件、不変条件で通常そのプログラムの内部で記述するものです
> (というのは平鍋さんのほうが詳しいと思います)が、それを外側にもってきた
> のが、XPのテストということでしょうか。
>

私は、表明とXPのテストは、レベルが1段階異なると思います。

まず表明、テストの一般論として、、

表明は、事前条件が満たされる時に、そのメソッドを実行すると
必ず事後条件が満たされていなければならない、とか、オブジェクト
は常にその不変条件を満たしていなければならない、とかいう
もので、ざっくりといえば、仕様だと思います。しかし、表明を定義
しただけでは、クラスがそのとおりインプリメントされていることが
保障されているわけではありません。プログラマは、表明を *実現*
しなければなりません。

テストは、その、実現(インプリメント)が、表明を正しく満たしているか
を確認するものだと思います(おっと、正しく  を 確認する、という言
葉遣いはマイヤーズさんの考えからはよくないのですが、今はわかり
やすいよう、一応そう言っておきます)。個々のテストケースあるいは、
個々のテストの実行は、表明そのものではなく、表明 の 実現 に
対する実証、あるいは反証ということですね。

次にEiffelの場合、

Eiffelの場合は、表明をプログラムの中に書けるのですが、
私はあまり詳しくなくて、仮定的にいいます。
もし、仮にEiffelがコンパイルレベルで表明が正しく実現できることを
チェックできるとすれば、テストは不要になるでしょう。つまり、コンパイル
の中でロジックの意味的な解析まで行うということです。

#表明とそのインプリの証明についてはホーアの理論とか、プログラム検
証論とかで、研究されているのだと思いますが、一冊本を読んだ程度なの
で、それが全ての場合で自動化できるのかどうかは知りません。

ただこの場合でもテストがない、というのは正確ではなくて、実験
によるテストが不要になっただけで、表明 と そのインプリメンテーション
が別に存在する以上、そのインプリメンテーションが表明を正しく実現
できていることを検証しなければならないわけで、それをやっている
こードの解析は、いわば、数学的、理論的アプローチによるテストだと
いえると思います。

また、もしEiffelがランタイムでしか表明に対する矛盾を検出できない
とすれば、表明を持つクラスやメソッドについて、やはりインプリに対する
従来の意味でのテストが必要だと思います。表明は書いてあるけれ
ど、本当にそうなっているの?というわけです。あるいは、事前条件と
事後条件しか書いていない(メソッドの本体部分がない)メソッドをイメ
ージしてください。

次にXPのテスト、あるいはJUnitの場合、

XPのテストは、従来のテストよりも積極的意義が加わっていると思いま
すが、それでも表明との関係で見た場合、表明そのものではなく、表明
の インプリ に対する、検証である、という点には変わりはないと思います。

ですから、例えばある表明に対しては、それを反証するテストケースを
いろいろ考えなければなりません。nullならどうなるとか、1ならどうなるとか、

ありえない日付ならどうなるとか、、、、


>
>  そういう意味でいうとMyersの定義である
>
> テストは、エラーを見つけるつもりでプログラムを実行する過程である。
>
>  とは外れているので従来のテストと同列に扱うことはできませんね。
>

マイヤーズさんは、いろんな角度からテストについての戦略を
出しているので、マイヤーズさんの意図とXPのテストの考え方が
全てにおいて合致しているわけではないと思いますが、上の「エラーを
見つけるつもりで、、、」というのは、(K.Beckがどう思っているかはさて
おき)、XPのテスト、あるいはJUnitを使ったテストでも、適合できる原則
だと思っています。ようは、テスティングするときの心がけの問題なので、
どれだけバグを健在化できるかに集中してテストケースを出せるか、という
問題だと思うのです。あ、健在というと既にあるかのような印象を与える
ので、ちょっとまずいですね。将来書かれるコードに、入りこむであろう
バグを先取りして予想してテストケースを書く、ということです。

特にブラックスボックスの場合でいえば、そのメソッドのシグニチャや
リスポンシビリティが決まれば、中身が書かれる前にもテストは書ける
はずです(だからブラックボックス)。その場合に使える(つまりは効果的
なテストケースを書く)ための戦略が、例の、同値分割、限界値分析、
原因ー結果フラグ、エラー推測などで、これは、JUnitを使ってテストケ
ースを書くときにも充分使える戦略だと思っています。

>
>  私がXPのテスト戦略に関して危惧しているのは、この方法では1歩間違う
> と、Boris Beizerが以下で指摘しているようなことに陥る可能性があるからで
> す。
>
>

(略)

>  また、privateメソッドをテストするしないの基準に関しても、従来のテス
> トの考え方からすると、
>
>  C1(ステートメントカバレージ)より少ない基準でユニットテストをする場合
> には、どの部分をテストしないで残すかを決定しなければならならない、。未
> テストの部分が、どんなバグに対して耐性があるか考えてみるとよい。バグに
> 対して特別な免疫がないなら、テストする/しないの基準はなんだろうか。そ
> んな基準は、独断的で合理性に欠け、救いようがない。実際問題として、テス
> ト未完の部分を残すことはよくあるし、そのために、システムがダウンするこ
> とがよくある。テスト未完のコードをシステムに組み込む言い訳のうちで最も
> 大きいのが、テストの時間や金が十分でなかったということである。時間と金
> がなくてテストできないのなら、そもそもプログラム開発の最初から金と時間
> がなかったはずである。テストが十分でない限り、コードはソースコードやプ
> ログラムたり得ず、単なるソースプログラムの原型、あるいは、タチの悪いプ
> ログラムもどきにすぎない。そんなデタラメをシステムに組み込むと、バグは
> たちどころに姿を現すが、ユニットテストが不充分なため、バグはなかなか見
> つからない。それこそ、Hannah Cowleyのいうように、「殺人のごとく、空し
> きものは露見する」。テスト未実施のソースコードにバグがないと思うことは
> 空しいことであり、それをシステムに組み込むのは殺人行為である。テストが
> 終わっていないプログラムは、システムの中に入れずに、まとめて別の場所に
> 格納する方がよい。システムの中に混入しない限り、テスト済みのプログラム
> に悪影響を及ぼすことはない。組み込んでいない機能は、当たり前のことだが
> 動作しない。未テストのコードは、動くこともあり、動かないこともあるが
> (恐らくは動かないだろうが)、未テストプログラムが混入すると、正常に機能
> しているプログラムにまで悪影響を与える。テストの済んでいないプログラム
> をシステムの中に入れるのは、愚かな近視眼的行為であり、無責任のそしりを
> 免れない。
>

プライベートメソッドやホワイトボックステストについては、課題は残る
ところですね。JUnitの焦点は、ブラックボックステストであり、また公開
メソッドに対するものであると私は考えていますが、ならテストはそれだ
けでいいのか?という議論はあると思います。

>
>  何度も書いているようにXPのテストの考え方に反対しているわけではないの
> です。Test Firstは良い考え方ですし。ただ、このテストをしたから万事OKと
> いうのは危険な感じがするのです。

そうですね。XPを全てのケースでの銀の弾丸扱いする
のは危険だと思います。

認識の誤り、事実の間違いなどありましたらご指摘ください。
それと、捕捉やご反論等ありましたら、是非ご教示ください。

--
矢崎博英  firo@....jp