BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル バーチャルパネル: コードとテストの比率、TDD、BDD

バーチャルパネル: コードとテストの比率、TDD、BDD

原文(投稿日:2012/07/13)へのリンク

ここ数ヶ月、テストファースト vs テストラスト、コードとテストの比率BDDは単なるTDDなのか、という話題が取り上げられています。InfoQはTDDとBDDの著名な専門家にTDD、BDD、テスト比率の使い方について話を聞きました。

パネリスト

  • J. B. Rainsberg氏 - コンサルタントでTDDの専門家。ブログはThe Code Whisperer
  • Dan North氏 - DRW Trading Groupのリーン技術の専門家。振る舞い駆動開発のチームを作った
  • Gojko Adzic氏- コンサルタント。著書に'Specification by Example'と'Bridging the Communication Gap'
  • Ron Jeffries氏 - XPとAgileのコンサルタント。オリジナルのXPプロジェクトでコーチを務めた
  • Steve Freeman氏- アジャイルトレーナー、コンサルタント。著書に'Growing Object Oriented Software, Guided by Tests'

質問

  1. あるプロジェクトの開発でTDDやBDDを使う(あるいは使わない)という決定を下すための条件は何だと思いますか。
  2. TDD = 単体テスト、BDD = 受け入れテストという考え方が一般的なようです。この考え方はどの程度正しいのでしょうか。また、この考え方の場合、コンポーネントテストやシステム統合テストのような他のテストはどのように考えればいいのでしょうか。
  3. 長年にわたり、TDDは(コード)設計の原則として、テストの原則として、そしてコミュニケーションのツールとして言及されてきました。TDDのこれらの異なる性質は設計にどのように影響を与えるでしょうか。また、現在のテストの価値と将来のテストの価値に対してはどんな影響がありますか。
  4. 自動化やメンテナンスのコストを考慮に入れて、単体テストと統合テストと受け入れテストの比率を決める事前条件を教えてください。
  5. 命にかかわるシステムを別にすれば、100%のテスト網羅率を目的にすべきでないことは共通認識になっていると思います。コードに対するテストの大きさやテストをする努力の度合いはより効率的で集中したテストを実現するでしょうか。
  6. TDD、BDD、ATDD、テストファースト、例による仕様などの概念の捉え方は人によって違います。私たちはこれらの手法について普遍言語を持たずに、文脈に依存した優れた実践を共有しているの状態なのでしょうか。

InfoQ: あるプロジェクトの開発でTDDやBDDを使う(あるいは使わない)という決定を下すための条件は何だと思いますか。

JB:この件について一般化するのは嫌なので、私がTDD/BDD使うときとその理由を説明させてください。

私が初めてTDDに出会ったのはミス(欠陥といってもバグといってもいいでしょう)を防ぐ方法を求めていたからです。プログラム上の多くのミスのおかげで私は完璧さの感覚を失ってしまいました。どんなことを成し遂げても仕事が完璧に近づいたと感じたことはありませんでした。そして、書いたコードをテストすれば、ばかげた小さなミスを見つけ修正できるのではないかと考えました。テストをしてミスを見つけたかったのは、愚かにみられるのを防ぐためというより、仕事に対する完璧さの感覚を失わないようにするためです。実際テストは役に立ちました。数年経って、TDDはコーディングのミスを防ぐのに役に立つだけでなく、デザインの失敗を防ぐのにも役に立つことに気づきました。そしてBDDを学び、どのような機能を実装するかについての失敗を防げることがわかりました。長年、ミスの修正にかかる時間と労力は優れた仕事をするための時間と労力よりも大きいと考えていたので、TDDとBDDは私にとって最も重要な手法になりました。

初めの質問に戻りますが、私は開発者がTDDを用いる理由を明確に表明し、その目的を達成するためにTDDを使うように促しています。より良い設計、より少ない欠陥、より価値のある機能、無駄な労力の削減など、TDD/BDDを実践する典型的な理由のほかに、個人的な理由を見つけ、それに注力するようにアドバイスします。私の場合はひとつの仕事が終わったということをもっとしっかりと確信したかったのです。思うにこのような動機は人それぞれのはずです。

Dan: まず、いくつかの緩い定義をしたいと思います。TDD は書いたコードをそのコードを使う側からの視点で考えるプログラミング手法です。この手法によって新たな設計が生まれます。テストを書くことは、テスト対象のコードがどのように使われるのかを記述することで、そのテストに通るように対象のコードを書きます。この手法はプログラマの専売特許で適切に使えばたくさんの利点があります。テストを書くことでドメインへの理解が深まり、命名がしやすくなります。テストすることで理解のギャップが明確になりますし、自動化されたテストが一式あれば退行的な欠陥を見つけられます。

私は「あるプロジェクトでTDDを使うべきかどうか」の基準があると思いません。TDDはどんなプロジェクトでも使えるはずです。しかし、プログラマがTDDが役に立つと思える状況だけで使うのがよいと思います。 設計やドメインの探索、モデリングや回帰的な欠陥を防ぐ方法はTDD以外にもあります。TDDがこれらを実現するのに最も適した方法の場合もありますし、そうでない場合もあります。しかし、そうはいってもTDDはすべてのプログラマが身に着けておくべき便利な手法だと思います。リファクタリングについても同じことが言えます。リファクタリングを知らないなんて言い訳できないことですが、経験を積めばどのような状況でリファクタリングを行えばいいのかわかるようになります。

BDDは開発の方法論です。プログラミング手法のTDDよりは、XPのような方法論に近いです。互いに視点の違う利害関係者を同じ土俵に乗せ、同じものを評価し、同じ期待値を持つようにするための方法論です。利害関係者の価値観の相違に起因する問題がなければ、BDDを使う必要はないかもしれません。私も最近はBDDを必要としていません。とても小さなチームで働いており、利害関係者からのフィードバックもすぐに受け取れるからです。「それ、変えてくれる?」「そうじゃない。サンプルを見て」で済んでしまうのです。

BDDはビジネスの目的を出発点にして、その目的を達成するための機能やストーリーを記述します。受け入れ条件をどのように構造化するか、受け入れ条件をどのように自動化テストに落とし込みコードの振る舞いを規定するかを示します。それゆえ、BDDに投資するという意思決定はプロジェクトレベルで行われるべきで(プロジェクトの一部分に適用するという考えもあると思いますが)、チーム全体を巻き込む必要があります。

チームとコードベースに敬意を払っているなら、プログラマにはどんな仕方でもしたいようにソフトウエアを開発する権利があると思います。チームメイトの協力が得られるなら、TDDを使いたければ、使わせるべきであり、ほかの方法がいいのならその方法を認めるべきです。

Gojko:TDDとBDDをどのように定義しているかに依ります。ここ数年、TDDは単なる単体テストを伴う技術的設計というとらえ方に狭まり、BDDは例とビジネス志向のテストでビジネス要件を満たす機能を獲得するためのキャッチフレーズになっているようです。Lisa Crispin とJanet GregoryのAgile Testingに書かれてるアジャイルテストの用語分類では、TDDは「チームをサポートするための技術に面したテスト」、BDDは「チームをサポートするためのビジネスに面したテスト」にそれぞれ分類されるでしょう。私はこの分類に必ずしも賛成ではありません。しかし、あなたの質問の仕方から類推するに、あなたはTDDをBDD や他の手法とは別のものとして定義しているようですね。では、その仮定の下で3つの条件を説明したいと思います。

そのプロジェクトは作り捨てですか。技術的な不確実性を低減して、本当にほしいものに対する技術的な視点を見つけるためのスパイクを作るプロジェクトですか。このような場合、大きな自動化テストは無駄になるでしょう。実際に役に立つのは少数の比較的小さなユースケースです。事前に技術的なテストを書くのも問題かもしれません。隠れた技術的制約がわかっていないのですから。いくつかのガイドとなる技術的テストを書くかもしれませんが、すべての設計を技術的単体テストを使って決めることはしません。設計の決定はSteve FreemanとNat PryceがGrowing Object Oriented Softwareで書いている規模の大きいシステムテストの役割でしょう。

プロジェクトの主要な複雑さは技術に起因しますか。達成したいことを技術的にどう実現すればいいか理解しており、ビジネス上のリスクや不確実性は少ないですか。プロジェクトのメンバは皆技術者ですか。コードは読めますか。例えば、ウェブフレームワーク、データベースプラットフォーム、キューイングシステム、クラウドシステムの開発は該当します。ほとんどのオープンソースプロジェクトも該当するでしょう。この場合、TDDは使えます。単体テストを使って利用シナリオや設計を作ることができます。ホワイトボードに例を書いて理解の共有を図ることもあるかもしれませんが、このような実例をCucumberのような実行可能な自動テストツールに取り込むのは時間の無駄なのでやりません。

対処すべきビジネス上の複雑さやはありますか。ソースコードが読めない人と話し合わなければならない、不明確な要件のリスクはありますか。この場合は分割統治を行います。ビジネス要件を探るために実例を使い、ビジネスと価値提供についての理解を共有します。そしてそれらの実例から仕様を作り、 それらの実例をCucumberやFitNesse を使って自動化します。そして、単体テストを使ってコードの設計を進めます。

Ron:私は半世紀に及ぶソフトウエア開発のすべてのプロジェクトでこの2つの手法を使ってきました。とはいっても、私がこの2つの手法を発明したのではありません。単に初期に学んだということです。この2つの手法から他の手法にはない確信を得ました。失敗は少なくなりましたし、設計もどう改善するべきかがわかるようになりました。

もう手放せません。

Steve:システムにテストが必要ですか。必要なら先に書いてしまえばいいでしょう。簡単にテストするのに必要なこともわかります。書くべきすべてのテストを把握しているのではないのですから、順次書いていけばいいのです。

InfoQ: TDD = 単体テスト、BDD = 受け入れテストという考え方が一般的なようです。この考え方はどの程度正しいのでしょうか。また、この考え方の場合、コンポーネントテストやシステム統合テストのような他のテストはどのように考えればいいのでしょうか。

JB:私はTDDは設計についてのフィードバックを与えてくれる手法、BDDは開発したい製品に対する理解についてのフィードバックを与えてくれる手法というふうに区別しています。私はテスト手法としてTDDを使い始めましたが、次第に設計手法として、そして、より優れたモジュール設計の原則を学ぶための手法として実践するようになりました。また、BDDは現実のユーザや利害関係者の視点から製品を見るための手法として使い始め、次第にビジネス側の人間と技術者の橋渡しをする手法として実践するようになりました。テストそのものは重要ではあるものの、このような実践の一部を占めているにすぎません。

TDDもBDDも単なるテスト手法だと思っていません。私が想定しているのは、TDDとBDDを横断するテスト戦略です。TDDを実践しようがBDDを実践しようが、私が求めるのは小さな単位のテストであり、システムテストであり、ユーザビリティのテストなのです。

Dan:そのような理解は不幸な歴史の産物です。TDDもBDDのそれ以上のものです。Kent BeckのExtreme Programming ExplainedでのTDDの説明はGrowing Object-Oriented SoftwareでのNat PryceとSteve Freemanの説明と同じです。つまり、TDDはさまざまな粒度で動作するということです。ユーザレベルの機能テストと低レベルの単体テストをコードがどのように振る舞うのが望ましいかを記述するために書くことができます。TDDは活動というより動機なのです。単に自動テストの網羅率を向上させるためにテストを記述するのはTDDではありません。並列実行や遅延、フェールオーバーやスループットなどの非機能要求もテスト駆動で設計できます。

BDDのユーザレベルのテストとコードレベルのテストの違いははっきりしています。ユーザレベルのテストは自動化に使えるように構造化されたシナリオの形式になります。シナリオの一部分は別のシナリオにも使えます。コードレベルテストは実例と呼ばれます(あるいはスペックとも呼ばれますが私は好きではありません)。これは一般的なTDDの理解に近いのではないのでしょうか。ユーザレベルのテストとコードレベルのテストにはさまざまなツールが現れました。ユーザレベルのシナリオでは開発言語に捕らわれないCucumberのようなツールが、コードレベルの実例では言語に特化したRSpecやNSpecがあります。私自身の経験ではチームが使いやすいツールを使います。なので、私が書いたBDDのコードのほとんどはJUnitとJMockのHamcrestライブラリを使っています。現在はPythonのpy.testとnode.jsのnodeunitを使っています。nodeunitはJUnitと同じような使い方ができますが、JUnitにもnodeunitにも"BDDスタイル"のフレームワークがあります。実例は単なるコードです。どのように構造化するかは開発者次第です。

Gojko:これもTDDとBDDや関連の概念をどのように定義するかに依ります。私は、Kent Beckは顧客テストと単体テストをTDDに属するものにしたと思います。また、私の理解では、Nat PryceとSteve FreemanがGrowing Object Oriented Softwareで示した考え方ではTDDはシステムテスト、コンポーネントテスト、単体テストを含みます。Specification by Exampleで私が紹介した方法では、優れた生のドキュメントでビジネスの概念を分解します。そしてどれを自動化するかはリスクの網羅の問題になります。そして、一番リスクの大きい実例は実例は単一のJavaメソッドで検証しています。また、30のウェブサービスを使い、100のデータベースを使ったシステムで実行しています。

Ron:BDDはTDDの異なる定義として始まりました。今や、Chris MattsやLiz Keoghのような人々の手によって、BDDは機能と受け入れテストの記述する手法に変わりました。

他のテスト手法ももちろんまだ価値があります。特にユーザエクスペリエンステストは重要です。コンポーネントテストや統合テストについて言えば、優れたアジャイルプロジェクトは継続的統合を導入しているので、コンポーネント単位で扱うことはほとんどなく、統合されたシステムに対するテストが多くなります。しかし、これらのテスト手法の区別は曖昧で、普通はさまざまなテストがあり、さまざまな間隔で実行されたり、さまざまなイベントをきっかけに実行されたりしています。例えば、ライブラリが新しくなったときや新しくビルドするときです。これらのテストには、単体テストや受け入れテストなど20年も前からあるようなテストも含めすべての種類のテストが含まれています。

重要なのはテストが必要なものをテストすることであり、作成したとき、変更したときに可能な限りテストすることです。そうすれば、たいがいの欠陥を防ぎ、見つけることができます。

Steve:私はTDD = 単体テストとは思っていません。その見方はTDDに対する誤解を元に広まったように見えます。TDDの根本にある問いは"それが動くのなら、動くことをどうやって確かめるか"、ということです。この問いがすべてのレベルの根底にあります。

テストを分割して便利にするという考えにも確信が持てません。この考えは一連のテストを作ることでシステムが問題なく動作することを開発者に示すという考えです。

InfoQ:長年にわたり、TDDは(コード)設計の原則として、テストの原則として、そしてコミュニケーションのツールとして言及されてきました。TDDでは、これらの異なる性質は設計にどのように影響を与えるでしょうか。また、現在のテストの価値と将来のテストの価値に対してはどんな影響がありますか。

JB:開発者次第だと思います。 私がTDDを始めたときは、テストの側面にだけ価値を見いだしていました。というのはまさにその側面を改善したいと思っていたからです。そしてミスが劇的に少なくなるとTDDが設計改善のためのフィードバックを与えてくれることに気付き始めました。このような気付きは、TDDで書いたテストコードの価値を極めて個人的な仕方で受容しているということです。テストを書いた開発者は自身が求めている価値をテストから得ることができると思います。

私はテストの現在の価値は、テストの未来の価値より高いと思います。数ヶ月後に既存のテストをすべて捨てて必要な部分だけ書き直すことを考えたりもしますが、実際にやったことはありません。

私は自分が書いていないテストからは大きな利点を得たことはありません。これは私の関わったプロジェクトにどの程度原因があるのか、またTDDの実践者の一般的なレベルにどの程度原因があるのかはわかりません。これは問題です。というのは、自分自身がお客の家に入って以前に行われた改修に文句を言うことから始める建築業者みたいになってしまうからです。

また、TDDスタイルのテストは変更検出(Cem Kanerの言葉で言うところの)のプールとして動作するという主張をしてきましたし、そのような主張を目にしてきました。確かにその通りの利点がありますが、私は詳しく検証したことはありません。また、システムやAPIをまだ見ていない人に対してテストを書くことで説明ができるという考えもあります。しかしこの考えは、私にとっては仮説のままです。

Dan:TDDは設計の原則です。それ以外は二次的な効果です。"テスト駆動"という言葉の"テスト"とは不幸な言葉で、振る舞いを記述するために書いた実例は事後になって初めてテストになります。コードを書いているとき、そのコードは望ましい使い方を書いたに過ぎません。継続的統合のような手法と連携することでこれらの一式のテストは回帰テストなります。しかし、そのような回帰テストがあったとしてもテストの必要性はなくなりません。特にBrian MarickとJames Marcus Bachが主張する技術が必要な直接的な探索型のテストは必要です。TDDのもうひとつの特徴は決定する力です。回帰テストの中で効果を発揮しますが、曖昧な部分を見つけるという観点から考えると弱点でもあります。ランダムでテストする手法では無数の細かい点を洗い流してしまいます。そのような細かい点はTDDでテストしてから排除すればいいのです。HaskellとScalaのツールであるQuickCheckはこの良い例です。

コミュニケーションについてですが、まさに私がTDDを導入する理由です。特にプログラマ同士のコードについてのコミュニケーションを促すことが重要です。BDD入門という記事で私は、自分の知らない原因でテストに失敗したときに、その失敗がどうして起こったかわからなくても、そのテストの意図を共有しておくと便利だと説明しました。TDDのコードはひとつのお話として読み、各テストの名前は機能に関するある程度の説明として読むことができるのです。

Gojko:TDDの使い方のバランスに答えが隠れていると思います。TDDをひとつの原則として考えるには、設計の原則として、テストの原則として、そしてコミュニケーションのツールとして使うためのひとつの方法を見つける必要があります。優れた単体テストは設計を進めますし、致命的に重要な技術的課題のリスクを低減し、対象のコードが何を実現しようとしているかについてのコミュニケーションを促進します。

Ron:TDDはテストを使います。しかし、TDDはテストに関する手法ではありません。作りたいシステムを作るための手法であり、同時にテストとプログラムそのものの足場になります。TDDを使うことで反復的に安全にシステムを開発し、プロジェクトの始めから終わりまでコードの鮮度を保ち、鍛え続けることができます。どのくらい作業が完了しているかが明確にし、プロダクトオーナーとマネジメントが最良の次の一手を打てるようにします。プロジェクトの終わりに聞かされる悪い知らせは少なくなります。例えば、コードがバグだらけだったとか、設計が悪くて素早い開発に耐えられないというような悪い知らせです。

これらのTDDの価値は"別々"のものではありません。ソフトウエア開発を成功させるには多くのアイディアを統合し、多くの目的のバランスを取る必要があります。それぞれの目的を交換したくありません。それよりも、すべての目的を達成する方法を求めます。そうすることで最速で最高の製品を作ることができるからです。

Steve:私はテスト(すべてのレベルでの)のコミュニケーションの側面を強調しようとしています。その他の側面にも良い影響があるからです。例えば、テストを読みやすくしておくと、あるオブジェクトに不適切な責任を割り当てようとしているのがすぐにわかります。

私が見た多くのチームがテストをメンテナンスできないほど腐らせてしまい、進捗の邪魔になっていました。テストコードはプロダクションコードと同様に手入れが必要です。特に新しい理解や概念が現れたときはメンテナンスしなければなりません。

InfoQ:自動化やメンテナンスのコストを考慮に入れて、単体テストと統合テストと受け入れテストの比率を決めるための事前条件を教えてください。

JB:TDDを実践し始めて1、2年経ち、テストのコストと利益のバランスが崩れているチームからよく相談を受けます。なぜバランスが崩れるかというと、小さなこと(個別のオブジェクトの詳細な振る舞い)を確認するのに大きなテスト(統合テスト、システムテスト、エンドツーエンドテスト)をしようとするからです。その結果、テストケースは長大で脆弱になり(ひとつのミスで23のテストが失敗する、というような)、開発者はテストのメンテナンスをしたくなくなります。テストは腐り、役に立たなくなります。

このような場合、小さなテストを書いて小さな振る舞いをテストすることと、結合テストと規約テストを用いて対象のレイヤをインターフェイスを接している別のレイヤと繋いでテストすることを学ぶように、そして、それ以外のテストはしないように助言します。つまり、統合テストとシステムテストから"基本的な正しさ"をチェックするように助言しているのです。"基本的な正しさ"とは、無限の空間と時間の中で、テスト対象のオブジェクトが正しい計算をするということです。

プロジェクトごと、チームごとに詳細は違いますが、私はプログラマには統合テストから小さなテストへ移行するように頻繁に勧めています。

Dan:比率を推奨するのは役に立つと思いません。むしろ、リスクになると思います。ミスが起きやすそうだったり、ミスの影響が大きそうな場合は詳細にテストする必要があります。例えば私の場合、データを転送するコードはテスト駆動で書きます。データ転送は汚くなってしまう場合が多く、問題を見つけるのも困難だからです。同じように外部と連携するシステムの場合は送受信するデータを慎重に扱います。バグが見つかったら、バグを分離するためのコードを書き、テスト駆動で修正する場合もあります。また、REPL(コマンドラインインターフェイス)でバグを見つける場合もあります。

Gojko:これはあまりにも一般的すぎる質問で、具体的なプロジェクトに即して考えないと答えられません。

Ron:"実践する"以外にありません。TDDを使えば少ないコストで優れたコードが欠けます。TDDを実践すると開発が遅くなると感じるチームや開発者もいます。開発案件によっては遅くなる場合もあるかもしれませんが、私はそのようなプロジェクトに遭遇したことはありません。多くの場合単にTDDに慣れていないだけです。したがって、素早く開発して欠陥の山を築いてしまい、おかしな設計になってしまい、その結果また欠陥が増え、バグを直すのが大変になり、プロジェクトは進捗し難くなるのです。プロジェクトの最終週には悪い知らせを聞くことになるでしょう。

これでデスマーチが生まれます。人も製品もデスマーチを生き残るでしょう。残念なのは多大な努力を払い生き残ったあげく、チームが何を達成するにしろ、この方法以外の方法はないと信じてしまうことです。これは間違いです。彼らはもっと単純な方法で優れた結果を得られる方法が身近にあるにも関わらず、自滅寸前の状態になってしまったのです。

Steve:推奨はできません。というのは、あるプロジェクトのテストの比率を見積もるには、同じチームで同じようなシステムを開発した経験が必要だからです。アジャイルのポイントは状況に対して適切に反応することです。プロジェクトが生きている間、比率は変化し続けます。

InfoQ: 命に関わるシステムを別にすれば、100%のテスト網羅率を目的にすべきでないことは共通認識になっていると思います。コードに対するテストの大きさやテストに対する労力の度合いに目標を設定することで、より効率的で集中したテストを実現するでしょうか。

JB:そのような目標設定すると、組織は役に立たない"成熟モデル"というのを作りますが、これは我々の職業にとって災難です。おそらく次のようなモデルでしょう。レベル1は"テストを書く"、レベル2は"すべての新しいコードにテストを書く"、レベル3は"システムの50%を網羅する"、そしてレベル5は"テストの夢を見る"。ほんとうにうんざりするモデルで的を外しています。このすべてのレベルを達成してもがらくたのような製品が生まれるのです。このようなモデルは本当に頻繁に見かけます。私が教えたことをぶちこわしにしてくれます。

私自身、このことを気にし始めたのは"ネットワークモーメント"が訪れたときです。つまり、"もう我慢できない。こんなこともう御免だ"と思ったときでした。私は皆が自分のネットワークモーメントに出会うのを支援し、問題を解決するためのアイディアを与えようとしています。テストの網羅率に目標を設定するよりも効率的に規律ある開発を生み出すことができるからです。

Dan:コードとテストの比率を事前に決めるのは逆効果だと思います。コードとテストの比率を事前に決めるということは、すべてのコードは同じ価値を持ち、同じリスクを孕んでいることを想定していますが、これは正しくありません。代わりにコードの種類に応じてテスト網羅性や細かさのレベルを適用するのがいいと思います。コードベース全体を均一にテストで網羅する場合の機会費用は甚大です。特にユーザインターフェイスは大変です。そのような作業にかかる時間はコードの質を高めるのに使ったほうがいいでしょう。

Gojko:網羅率を目標にするのは馬鹿げています。最もリスクが大きいコードを10%網羅することは、リスクのないコードを99%網羅することよりも遥かに優れています。テストの網羅率よりもリスクの網羅率のほうが優れた指標だと思います。私はAttribute Component Capability Matrixを使ってリスクを評価し何をどのように網羅するかを決めています(James WhittakerのHow Google Tests Softwareを参照ください)。

Ron:テストの網羅率は目標にするべきではありません。テストが十分ならテストした部分に問題が少ないのは明らかです。ではどこに問題が残っているのか。テストしていない部分です。完璧ではない網羅率が"十分"かどうかという視点で考えるのは適切ではありません。代わりに2つのことが必要です。

まず、テスト技術を磨き続け、システムのテストされてない部分を少なくすることです。また次のことも価値があるでしょう。すなわち、本当にTDDに従うなら"失敗したテストに対応するコードだけを書きなさい"。そうすれば、自動的にコードの行の網羅率は完璧になり、処理の流れの網羅率も十分になります。

そして、チームで網羅率などの情報を分析し、どの部分のテストを強化するのかを決めます。この作業は完璧にはなりませんので、注意深く行い、欠陥が見つかったら何が起こっているのか把握して、足りないテストを書き、同種の問題が再発しないようにします。

Steve:これも、データがない状態での予断になってしまいます。多くの場合コードの網羅率が役に立つかどうかはあいまいです。網羅率は見るべきコードを探すのに役に立ちますが、外部から与えられた目標になってしまうとチームの焦点をゆがめてしまいます。

InfoQ:TDD、BDD、ATDD、テストファースト、実例による仕様などの概念の捉え方は人によって違います。私たちはこれらの手法について普遍言語を持たずに、文脈に依存した優れた実践を共有しているの状態なのでしょうか。

JB:私はそうは思いません。さまざまな実践について十分な用語を持っていると思います。定義の仕方について不安になるのを辞めて、自分の理解を共有し他人にも理解を共有してもらうように促すことで、以前より良い結果が得られるようになりました。TDDとBDDの定義や意味についてはあるホテルでDan NorthやChris Mattsなどと議論しましたが、私の人生の中で最も影響受けた議論でした。ひとつの定義をコミュニティに押し付けてこのような生き生きとした重要な議論を抑制してしまうのはとても恥ずべきことです。

Dan:これは単に私たちが扱っている領域が進化の最中であるということを示しているに過ぎません。私がBDDを提案したのは、(私の理解している)TDDを教えるのを支援するためです。Gojko Adzicの"実例による仕様"という言葉が好きなのは、明確で普遍的な言葉だからです。テストや実例やスペックなどに関連する言葉には長い間苦しめられてきましたし、未だにどれがどれだか解りません。"普遍言語"という言葉自体も誤解を生みやすいです。"普遍"とはある境界内の世界を表します。言い換えれば、文脈次第で異なる仕方で同じことを記述できるということです。ある人のテストは別の人の実例かもしれません。他の人にとっては仕様かもしれません。特定の文脈の中で意図を明確にしているかどうかに関係するのです。

Gojko:実例による仕様という言葉に、明確で文脈がはっきりしていて、狭い定義を与えようとしたのは、まさにこの理由からです。TDD、BDD、ATDDなどの言葉との混乱を避けるためでした。ビジネスの視点から実例を使うことで開発するべきもの明確にし、生きたドキュメントを作って開発支援をすることが、この実例による仕様という言葉ではっきりと表されています。技術的なテストによって設計を駆動する方法とは別に、設計に役に立つ具体的な方法がありました。それを実例による仕様と名付けることでそれ自体を扱えるようにしたのです。

ATDDという言葉は好きではありません。間違った認識を抱いてしまい、チームが間違った方向へ進んでしまうからです。この言葉は使わないでほしいのですが、残念ながらこの言葉を広めるような書籍が出版されてしまいました。

BDDという言葉には、実例による仕様や単体テストによる設計駆動以上の意味が含まれていると思います。例えば、機能注入、要求引き出し、アウトサイドイン設計、ビジネス価値のための定義モデルなどはBDDの一部だと思います。また、エフェクトマッピングは計画作りの手法としてBDDの価値体系に完全に合致する新しい手法です。この手法はビジネスの目的にまでテスト駆動を適用しつつ、自動化は一切考慮されていません。

Ron:人間のコミュニケーションとはこういうものだと思います。全員が完全に同意する普遍的な言葉はありません。私たちのようなビジネスの場合、どこへ言っても学習が必要なので、理解の差異は避けられません。最も重要な差異はこれらの言葉を理解しようとしない人たちの中にあります。

このような態度は2つの悪影響を生みます。第一に多くのプロジェクトや個人が自分の想定していたよりも達成できなくなります。それゆえ、開発者は苦しみ、プロジェクトは失敗し、成果が上がりません。第二に誤解はこれらの優れたアイディアの正しい理解を妨げます。

Steve:原則について完璧に理解していれば、用語を取り出せるのですが。何をどこに当てはめるのはを明確にするのは時期尚早だと思います。また、違いを認識している別の"学派"が現れる余地もあると思います。

InfoQ: このトピックについて他に何か言いたいことはありますか。

JB:TDDもBDDも開発改善のガイドになるので実践してみてください。"個人的な達成"のために実践してください。仕事を楽しくするために使ってください。

Dan:これからもこの分野について情報発信をしていきたいと思います。

Ron:私が半世紀に渡り、これらの手法を使ってきたのはとても役に立つからですが、すべての人に使うように勧めることはしません。

しかし、開発者は皆これらの手法を十分に使いこなせるくらいに身につけておくべきだと思います。そして、その段階になって初めてこれらの手法を導入するかどうかを決めるべきだと思います。便利そうな手法を十分に学習して評価する前に拒否するのは間違いです。

私は開発者に私がソフトウエア開発でやってきたことを見せ、自ら試してみることのできる安全な場所を提供し、これらの手法を使うかどうかの意思決定がしっかりできるような感覚を残してやりたいのです。

私は常にこれらの手法を使うという決定を下しています。他の開発者もこれらの手法に同じ価値と利点を見いだしてくれることを望んでいます。

Steve:私がチームとTDDについて話しているときは、多くの場合、テストについてではありません。基本的な設計技術の弱点についてです。テストを書くのが大変なのはコードの構造が間違っているからです。また、十分な表現力のないコードもあります。プログラマを面接する時は読みやすいパラグラフが書けるかどうかも確かめたほうがいいのではないかと思っています。

パネリストについて

J. B. Rainsbergerはソフトウエア企業が顧客をより満足させ、顧客のビジネスをよりしっかり支援できるようにするために働いています(jbrains.ca)。長年にわたり、価値あるソフトウエアの作り方を学び、社会性の欠如を克服して、自分の好きな人生を手に入れました。世界中を旅して、自身が学んだことをを広め、他の人々が仕事や人生から自分が求めるものを得られるように支援しようとしています。この2年はヨーロッパを旅していますが、アトランティック・カナダに妻のSarahと3匹の猫と暮らしています。ブログはThe Code Whisperer

Dan Northはソフトウエア開発者であり、企業でアジャイルやリーン開発の手法を教えています。人間を第一に考え、シンプルで実用的なソフトウエアを開発するというのが信条です。Danの考えでは、チームが直面する問題のほとんどはコミュニケーションに関連します。それゆえ、Danは"言葉を正確に使用する"ことを強調します。BDDやコミニュケーション、学習方法について情熱を傾けているのも同じ理由です。1991年に大学を卒業してからIT産業で働いています。ブログはdannorth.net

Gojko Adzicは戦略的ソフトウエアデリバリコンサルタントで、ソフトウエアと開発プロセスの質を高めるために野心的なチームと共に働いています。アジャイルやリーン開発の品質改善を専門とし、特にアジャイルテストやサンプルによる仕様、振る舞い駆動開発に詳しいです。また、ソフトウエア開発やテストに関連するカンファレンスでスピーカーを務めることもあり、UK agile testing user groupを主催しています。この11年間、開発者として、アーキテクトとして、コンサルタントととして、金融とエネルギーのトレードプラットフォームやモバイル位置情報システムやEコマースシステム、オンラインゲームや複雑な構成管理システムに関わってきました。著書にSpecification by ExampleBridging the Communication GapTest Driven .NET Development with FitNesseThe Secret Ninja Cucumber Scrollsがあります。

Ron JeffriesはXPとアジャイル(XProgramming.com)のコンサルタントで、ほとんどの人より長くソフトウエア開発に従事しています。オリジナルのXPプロジェクトのオンサイトのコーチを務めていました著書にExtreme Programming Adventures in C#、Extreme Programming Installedがあり、Object Mentorの人気のXPコースの共同制作者でもあります。

Steve Freemanは'Growing Object Oriented Software, Guided by Tests' (Addison-Wesley)の著者であり、イギリスのアジャイル開発の先駆者です。小さなベンダから国際的な投資銀行まで様々な組織でソフトウエアを開発してきました。現在は世界中のソフトウエアチームに対してトレーニングやコンサルティングを提供しています。以前は研究所やソフトウエアハウスで働きPhD(Cambridge)を取得しました。国際的なカンファレンスで発表したりすることもあります。第一回のLondon XpDayの議長も務めました。

この記事に星をつける

おすすめ度
スタイル

BT