« 三角形問題ではKent Beckにも見落としがあった! | Main | ソフトウェアテストの歴史年表の公開 »

17 June 2011

三角形問題のテストの考え方いろいろ

前回の記事で三角形問題のテストに関するcomp.lang.rubyの一連の議論が、TDDにおけるテストの考え方やテスト専門家の考え方が分かり、非常に勉強になりそうだと書きました。
この一連の議論は以下のGoogle Groupsのリンクで読めます(comp.lang.ruby beck triangle binder で検索した結果です)。174スレッドあり25スレッドで1ページになっているので適宜ページを進めて読んでください(Expand allにするとよいです)。
John Roth dolt ( Re: A challenge to proponents of Unit Testing. )
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/2ee4bea87846ead3/e32568d860adc89b?hl=en&q=comp.lang.ruby+beck+triangle+binder&lnk=ol&#

以下に、私なりに理解した(と思った)ことや注目したことを書いてみます(ただし、私の英語の解釈の誤りや技術上の誤解があるかもしれません)。

1. BeckのTDDのテストケース作成の考え方
1)Beckの実装では何故6個のテストでよいのか
  ・SmalltalkのSetの機能を使っているので入力値の順序を入れ換える(permutation)テストケースは不要(注1)
    → Myersの13個のチェック項目の内、permutationの確認は3項目あります。
  ・Smalltalkは整数が整数として扱われる(限界値はない)ため入力値の限界値のテストケースは不要(注2)
    →Myersの13個のチェック項目の中に限界値の確認はありませんが、Binderのテストケースにはあります。
  ・BeckのテストケースにはMyersのチェック項目の中の「一辺がゼロ」「二辺の和が他の一辺より小さい」「全ての辺がゼロ」「入力する個数の誤り」が含まれていませんが、その理由は分かりません。「テスト駆動開発入門」で書いているように「テストがなくても実装の知識により自信が持てれば、そのテストは作成しない」ということかもしれません。

(注1)Setは集合に対して重複しない項目のみを含むので、3辺が(2,3,4)の場合はSetオブジェクトは(2,3,4)、(1,2,2)の場合は(1、2)、(2,2,2)の場合は(2)となります。また、Setは3辺の値の入力順序には無依存です。そしてSetオブジェクトの項目数が三角形の種類を表すことになるので、1は正三角形、2は二等辺三角形、3は不等辺三角形を表すことになります(Beckは後にSortedCollectionを使う実装に修正していますが集合の観点からは同等)。

(注2)「テスト駆動開発入門」のp.192に「たとえば、Smalltalkの整数は整数のように振る舞い、32ビットコンピュータのようには振る舞わないので、MAXINTをテストする意味はない。」と書かれています。初めて読んだときは意味がよく分かりませんでしたが、comp.lang.rubyの議論を読んで「整数は整数のように振る舞い」という文章が、そもそも整数には限界値(32ビットコンピュータのような2**32-1という上限値)はないという意味だと理解しました。

2)その他のBeckの発言で注目したもの
  ・この5つのテストケースは私の機能のMTBFに対して大きな確信(confidence)を与えてくれる。
  ・SmalltalkではなくJavaでコードを書いて2**31を入力したらどうなるかを確認したければそのようなテストを書けばよい。
  ・unit testsが大量で複雑になる場合、それは設計(design)に問題があるのであってテストの問題ではない。

2. Binderのテストケース作成の考え方
1)Myersの三角形問題のテスト
  ・典型的な三角形判別アルゴリズムでは辺の長さの和をとる処理があるので、少なくとも一つの辺は(2**32)-1をテストして計算オーバーフローの確認が必要
  ・また、二辺の確認だけで判定してしまうというバグがよくあるが、これがMyersがpermutingのテストを主張した理由

2)その他のBinderの発言で注目したもの
  ・テスト対象の実装の知識はテストを作成する助けにはなるが、危険を伴う。
  ・テスト作成のゴールはテストスィートを最小化することではなくバグ検出機会の最大化であるべき。
  ・テストのコミュニティでは適切なテスト(adequate testing)は少なくとも命令網羅(statement coverage)を達成することと定義されているが、このスレッドの一連の議論はそうではなさそうだ。(カバレッジに関してBinderとJeffriesが議論しているが、私はあまり内容が理解できていません)

3. その他の参加者のやりとりで注目したもの
1)コードを書く前にテストを書くというXPのルールに反しているのではないか?
  → 違う。XPにおけるテストはコードの作成と同時(concurrently)に書かれる。(Robert C. Martin)
2)あなたのテストは特定の実装に特有のものなので、他の実装では適切なテストにはならない。
  → その通り。unit testはwhite box testであり、設計の変更に影響を受ける。一方、acceptence testはblack box testであり設計の影響は受けない。どちらのテストも必要だ。(Robert C. Martin)
3)テスト対象の実装の知識は助けになるが危険を伴う(Binder)
  → その通り。XPではこのジレンマに対して2つのテストスィートを用意することで解決している。ひとつは開発者が書くwhite box unit test、もうひとつは顧客/QA部門が書くblack box acceptence test。(Robert C. Martin)

<感想>
・TDDは「最初にテストを書く」ということから、Black box testしかあり得ないと考えていましたが、どうもそうではないらしい。
・Beck、Martin、JeffriesとBinderらの議論は、現場の開発担当者とテスト/QA担当者との間でもあり得るやりとりのように感じました。
・検査部門に長年いた私としては、テストを現実的な(実施可能な)数に減らすために、開発担当者とのやりとりを通じて「確信をもって」減らす、あるいはズームアウトするようなグレーボックステストのアプローチが現実解ではないかと思います。

|

« 三角形問題ではKent Beckにも見落としがあった! | Main | ソフトウェアテストの歴史年表の公開 »