TDDは死んだのか?
ケント・ベック氏、デイビッド・ハイネマイヤー・ハンソン氏、そして私との間で、テスト駆動開発(TDD)とそのソフトウェア設計への影響について行われた一連の対談です。
この対談の経緯
挑発的な講演とブログ投稿がきっかけとなり、お互いの見解と経験を理解することを目的とした対談が始まりました。
詳細…この対談は、デイビッド氏のRailsConf基調講演がきっかけとなりました。彼はこの講演で、RailsコミュニティにおけるTDDと単体テストへの不満を表明しました。その後すぐに彼はいくつかのブログ投稿を行い、最初の投稿では“TDDは死んだ”と宣言しました。
数日後、私は彼の次の投稿に誤字修正を送信し、彼は私の講演とブログ投稿への考えを歓迎すると言いました。その後、私たちはSkypeで1時間、楽しく有益な議論をしました。デイビッドはケントとも同様の議論を行い、ケントは私たち3人で議論を続け、その会話を公開することを提案しました。デイビッドはこのアイデアをツイートし、多くの肯定的な反応を得ました。
このシリーズに対して、私たちはそれほど計画を立てていませんでした。せいぜい30分の会話が6回ほどあるという大まかな考えしかなかったのです。私たちは主に、お互いの経験と見解を学びたいという思いからこれを行いました。私たちは、自分たちを見たいと思っている人がたくさんいると考えるほどナルシストなのです。初期のエピソードでは質問を受け付けていませんでしたが、最後の一つではいくつか質問を受け付けました。これを行う中で、ブログやTwitterで議論が続く様子を楽しんでいました。
特にウェズリー・クロック氏を含むThoughtworksに感謝します。彼はビデオ設定の調整やハングアウト時間の調整など、多くのロジスティクスを手伝ってくれました。各エピソードの後、私は視聴するよりも読むことを好む人のために、議論の議事録を作成しました。
1:TDDと自信
2014年5月9日
私たちは、TDDの流れ、そしてTDDと自己テストコードが混同されることの多い現状について話し合います。
詳細…
議事録
デイビッドは、TDDと単体テストに関する3つの主要な問題点を提起して議論を始めました。TDDと単体テストの定義に関する混乱、モックを使用してアーキテクチャを駆動することによるテストによって誘発される損害、そしてTDDの赤/緑/リファクタリングサイクルが彼にとって決してうまく機能しなかったこと。 私は、TDDなどがどこから来たのかを理解するには、その歴史を理解することが有用だとコメントしました。そこでケントはTDDの起源を説明しました。彼はSmalltalkで試行錯誤を始め、TDDが自分の性格に合っていることを発見しました。
私は、C3で初めて一緒に仕事をしたとき、TDDの使用は開始しませんでしたが、各プログラミングエピソードでコードとテストを一緒に提供するようにしましたとコメントしました。 ケントは、プログラマーは自分のコードが機能することに自信を持つに値し、TDDはその(唯一ではない)方法の一つであると言いました。 デイビッドはRubyのプログラマーの幸福という設計目標が好きで、テストが完了するまで作業は完了しないという考えには同意しますが、そこに至る方法としてのTDDは好きではありません。 彼は、人々の脳は異なり、したがって異なる技術や言語を好むと考えており、TDDが自己テストコードから得られる自信と混同されるのが嫌いです。
ケントはFacebookでの最近のハッカソンについて話しました。その約半分でTDDを使用でき、半分は適していませんでした。 TDD可能なコードでは、彼は楽しい流れの中にいることに気づきましたが、他の部分はより難しいと感じました。しかし、非TDD部分では、彼は回帰テストと短いフィードバックループを依然として使用していました。 彼は両方のスタイルを混ぜることに問題はありません。それはクラシックとジャズを両方演奏するようなものです。 TDDは、彼が学校で数学を学んだ方法を思い出させます。常に例が必要でした。
デイビッドは、TDDがうまくいく状況もありましたが、彼の仕事のほとんどはそのようではありません。彼の質問は、その流れを得るために何を犠牲にする意思があるかということです。 多くの人が、特に大規模なモックを使用して、悪いトレードオフをしています。 ケントは、それはトレードオフに関することだと考えています。中間結果をテスト可能にする価値はあるでしょうか? 彼は、中間解析ツリーが優れたテストポイントであり、より良い設計でもあるコンパイラの例を使用しました。 しかし、モックに関するデイビッドの質問に対して、彼はめったに使用しないと述べ、モックを使用する人はリファクタリングが難しいと感じる一方で、彼はテストによってリファクタリングが容易になると考えています。
私は、異なるものが混同されるという用語上の2つの問題があるとコメントしました。第一に、DHHのTDDに対する批判は、TDDでは大規模なモックを使用する必要があるという仮定に基づいており、それは事実ではありません。第二に、自己テストコードとTDDには違いがあります。TDDは自己テストコードを実現する一つの方法です。 デイビッドは、モックを多用したスタイルでTDDを説明する人々を見て、それが道徳的なことだと感じ、その結果、分離された単体テストを可能にするという願望のために、設計の悪いコードが大量に作成されたと言いました。
私はタイムコップとして、次のセッションでは、TDDが損害につながる可能性があるかどうか、それが本当に損害であるかどうか、そしてそれが損害であるかどうかをどのように判断できるかを検討すると述べて締めくくりました。
さらに読む
- すべてのはじまりとなったデイビッドのRailsConf講演。
- デイビッドによるTDD is Deadとテストによって誘発される設計上の損害に関するエッセイ。
- 私による自己テストコードとTDDの区別。
- 私による単体テストの定義へのアプローチ
2:テストによって誘発される設計上の損害
2014年5月16日
デイビッドは、TDDを使用すると、過剰な間接参照の複雑さのために、テストによって誘発される設計上の損害である六角形レールなどのアプローチにつながると感じています。ケントは、それはTDDよりも設計決定の質に関するものだと考えています。
この会話を見る前に、デイビッドが作成したgistを見て、彼が懸念している設計上の損害の例を確認してください。また、多くの人が惜しむジム・ウェイリッチが六角形アーキテクチャへのこのアプローチを探求している動画を見ることもできます。
詳細…
議事録
私は質問から始めました。TDDは設計上の損害につながる可能性がありますか?結果として生じる損害は本当に損害ですか?設計が損傷しているかどうかをどのように判断しますか? デイビッドは、以前に投稿したgistを説明します。これは、彼が多くのモックを使用してTDDを使用して到達するアーキテクチャの一例です。アプリケーションの各レイヤーは分離されており、たとえば、コントローラーは実際のモデル、データベース、またはリクエスト/レスポンスサイクルと通信せずにテストできます。 デイビッドにとって重要なのは、特定の例ではなく、それをより簡単に分離してテストするために必要な不必要な間接参照と複雑さです。
ケントは、テストによって誘発される損害をTDDに帰することは、車を悪い場所に運転して車を非難するようなものだと述べました。 デイビッドが示した設計はTDDによるものではなく、実際の問題は、これらの間接参照は状況によってはすべて良いトリックであり、それらがコストに見合うかどうかを理解する必要があるということです。 デイビッドは、TDDという馬(または車)に乗ると、ある特定の方法に進みたくなる - テストごとに怪物になると異議を唱えました。ケントは、それはむしろ一度に1つの設計決定だと反論しました。TDDは設計に進化圧力をかけます。人々は、テストによってカバーされる量の粒度に関して異なる好みを持っています。
ケントは、その構造が困難にすることをデイビッドに尋ねました。 (「それがただそこに座っているだけなら、どうでもいい。設計が本当に重要になるのは、変更したいときです。」) デイビッドは、コードのサイズと変更の容易さの間には直接的な相関関係があると答えました。これらの間接参照はすべて同期する必要があり、10行のコードは、60行のコードよりも理解して変更しやすいです。 間接参照の各レイヤーは高いコストをもたらします。 デイビッドは、TDDの赤/緑/リファクタリングの流れは非常に中毒性が高い (ケントは、彼が地球上で最も貧弱な麻薬売人だと観察しました)と続け、この中毒が人々をこれらの悪い決定に導きました。私はこれには反対し、それはTDDによるものではなく、分離への願望によるものであり、六角形アーキテクチャの本質は環境(この場合はRails)からの分離であると言いました。
デビッドは、人々がアイソレーションを望む理由はTDDによるものだと述べ、 アイソレーションの様々な議論を耳にしたが、テストに関するものだけが理にかなっていたと語りました。 Railsアプリケーションをコマンドラインアプリケーションに変えたいと思う人がいるという考えは、あまりにも稀で滑稽だと彼は考え、 同様に、動作特性が異なるため、インメモリストアをWebサービスへの呼び出しに簡単に置き換えることはできません。 これらの交換可能な夢のような考えは真の目的ではなく、真の目的は独立したテストです。 ケントは、インメモリとWebサービスを同じように扱うことはできない(「結合されていると思っていても、実際は全く結合されていない」)ことに同意しました。失敗ケースが異なるからです。 要素間の境界はある程度リークします。「問題は、要素間の結合をどの程度まで実現するために、どれだけの費用をかける意思があるか」です。
ケントは、10行のコードと60行のコードの違いを凝集性の問題だと見なしました。 デビッドは同意しましたが、凝集性と結合性はしばしば対立すると主張しました。より高い結合性は、より良い凝集性を得るためのコストに見合うことが多いです。 ケントは、外部依存関係を排除する他の方法として、中間結果を使用することもできると述べ、これはコンパイラで起こることだと指摘しました。 テストが難しいことは、設計上の洞察が必要であることを示しており、そのような洞察を見つけるために立ち上がって散歩することは、より優れたテスト可能な設計につながることがよくあります。 デビッドは、テストはより良い設計につながることに同意しましたが、彼の経験では、しばしばその逆で、テスト可能な良い設計が存在しないこともあったと述べました。 ケントは、デビッドに自信がないと非難し、今日の洞察は見えないかもしれないので、その間は進歩しなければならないが、最終的には見つけられると楽観的です。 デビッドはこれを「信仰に基づくTDD」と片付けました。彼は以前はそう感じていましたが、理想的な解決策が見つからず、憂鬱なループに陥っていました。 ケントは、TDDではなく、一般的なソフトウェア設計について話していたことを明確にし、 TDDではなく、フィードバックを得る方法についてです。ソフトウェア設計について考えることは重要です。なぜなら、優れた設計上の洞察を得ると、非常に大きな効果があるからです。 これらの洞察を得ることは、ワークフローではなく、いつ働くか、いつ休むか、他の場所からの影響を収集するか、他の人と協力するかといったことにかかっています。
次回のテーマは、プログラミング中にフィードバックを求める際のトレードオフを探ることになりました。
さらに読む
- デビッドのgistは、彼が懸念している設計上の問題の例を示しています。このgistは、ジム・ワイリッチによる講演で示された六角形Railsアーキテクチャの探求に基づいています。
- デビッドのブログ記事 テスト誘発設計損傷の問題を紹介
- 「六角形アーキテクチャ」という用語は、アリスティア・コックバーンによって最初に造語されました。「ポートとアダプタ」としても知られています。
- このハングアウトの後、同僚のバドリ・ジャナキラマンと、六角形Railsアーキテクチャの本質とその使用に関するトレードオフについて別のハングアウトを行いました。
3: フィードバックとQA
2014年5月20日
プログラミング中にフィードバックを得る様々な方法と、開発者にフィードバックを提供するQAの役割について議論しました。
詳細…
議事録
ケントは、TDDを含む意思決定はトレードオフに関するものであると述べて始めました。 「理想的な世界では、プログラミングの意思決定に関する即座で確実なフィードバックを得ることができるでしょう…」 「私が行うキーストロークごとに、コードがデプロイの準備ができている場合、ただちにデプロイされるでしょう。」 しかし、その理想は現時点では不可能であるため、問題は、そこからどの程度後退するかです。 彼はトレードオフにおけるいくつかの制約を列挙しました。
- 頻度: フィードバックをどのくらいの頻度で得たいですか? ?
- 忠実度: 赤/緑の信号をどのくらいの精度で得たいですか?
- オーバーヘッド: どれだけの費用を払う準備がありますか?
- 寿命: このソフトウェアはどのくらいの期間存在する予定ですか?(確率と時間)
これら4つが、比較する必要がある制約だと彼は考えています。 「このハングアウトで合意するわけではない。私の個人的な目標は、建設的に私の考えを批判してくれる人々に明確にすることで、トレードオフのセットを理解することだ。」
私は、フィードバックを得るために注目している3つのことを概説しました。
- ソフトウェアはソフトウェアのユーザーにとって有用なことをしていますか? テストが役立つ場合(給与計算など)と、そうでない場合(HTMLレンダリングなど)があります。
- 何かを壊しましたか? 「これは、自己テストコード…が非常に役立つところです。」 すべてのテストが少なくとも一度は失敗するのを見たいです。
- 私のコードベースは健全ですか? これは、物事を迅速に構築し続けるためです。誰がコードを引き継ぐかわからない場合、この要素はより難しくなります。
デビッドは、TDDの成功がQAの軽視につながったという話題を紹介しました。多くの企業はTDDを採用し、QAを廃止しました。 Basecampは数年前までQAがありませんでした。 彼はTDDによってプログラマーは「自分たちにはQAは必要ないと感じるほど過信するようになった」と考えています。古いモデルは破損していましたが、振り子は行き過ぎました。 「重要な品質のものを制作し、優れたソフトウェアを生み出すには、自分自身ではない人がテストする人が必要だと思います。」 これは残念なことです。なぜなら、彼はQA担当者が介入することの強力さを目の当たりにしてきたからです。
もう1つの問題は、トレードオフを理解するにはコストを理解する必要があるということです。TDDに関する議論はすべて、メリットに関するものでした。 このコストの軽視のために、テスト誘発損傷というものが存在することを理解できないのです。 トレードオフの連続性は、他のことにも当てはまります。信頼性の費用を考えてみましょう。99%から99.999%に上げることは、99%に到達するよりも指数関数的に高価です。 クリティカリティも考慮する必要があります。高い信頼性はスペースシャトルやペースメーカーにとって重要ですが、実験的なWebサイトにとっては間違っています。 テストなしでプロダクションコードを1行も書かないというルールは、クリティカリティに関するトレードオフには合いません。
ケントはQAの問題に戻りたがり、QAとの古い関係は機能不全に陥っていたと考えていました。 彼のオフィスにあるFacebookのグッズは、「Facebookでは何も他人の問題ではない」と書かれたポスターで、彼はFacebookがその規模の会社としてはそれを驚くほどよく守っていると実感しています。 Facebookは最近までQAがありませんでしたが、プログラマーはその責任を果たしています。 「それは『何に比べてか』の問題です。」効果的なQAと比較すると、QAなしの方が悪いですが、QAなしは古い機能不全の関係よりも優れています。 Thoughtworksでは、ほとんどすべてのプロジェクトでQAを実施していると付け加えました。 90年代からの大きな変化は、機能不全の敵対的な関係を解消することだけでなく、手動のスクリプトテストを解消することでもあると感じています。 スタートアップがQAなしで運営できるのは解放的です。 デビッドは、初期のスピードのためにQAを意図的にトレードオフするのは良いことだと同意しましたが、プログラマーのテストをやり過ぎ、探索的テストの価値が見えていない人もいます。 開発者がQAなしで十分な品質のソフトウェアを作成できると考えるなら、それは間違っています。テストはグリーンかもしれませんが、本番環境ではユーザーが予想外の行動をとります。
デビッドは、最悪なのは開発者がカスタマーサービスに関わっていない場合だと述べています。 多くのプログラマーは、オンコールを嫌がりますが、それはフィードバックループでもあります。 グリーンテストのコードは、あなたが望む場所よりも低いプラトーになる可能性があります。 ケントは、これらの限界を思い出させるために、グリーンバーにいくつかの赤いピクセルを散らすべきだと考えました。 「オンコールは、どのテストを書いていないかを教えてくれるフィードバックループです。」 Facebookのプログラマーはオンコールになる必要があり、誰もが不平を言っていますが、それをやめることはありません。 もう間違いを犯さないと考えるようになったら、それは間違いであり、成長が止まります。最終的には「世界は、あなたがもう失敗していないふりをさせてくれません。」彼は、午前2時の電話で早くそれをキャッチする代償を払う方が良いでしょう。
テストのコストについてさらに話す時間がなかったので、次回それについて検討することを提案して締めくくりました。また、偶然にも私のサイトで今日公開されたマイク・ブランドの記事が、まさにそのトピックについて取り上げていることを付け加えました。
4: テストのコスト
2014年5月27日
テストとTDDのいくつかの欠点について議論しました。テストが多すぎることはありますか?チームが機能コードよりもテストを重視することに問題がありますか?
詳細…
議事録
デビッドは、「トレードオフについて話すには、欠点を本当に理解する必要があります。なぜなら、欠点がない場合、トレードオフはないからです。」と述べて始めました。 彼は、TDDは物事を強制するわけではないが、特定の方向に促すものであると続けました。 彼が最初に提起した問題は、過剰なテストでした。コードを1行も書かずに失敗するテストを書くべきではないと言われることがよくありますが、最初は妥当に思えますが、プロダクションコード1行につき4行のテストコードがあるなど、過剰なテストにつながる可能性があります。つまり、動作を変更する必要がある場合、変更するコードが多くなります。 ケントは「テストを書くために給料をもらっているわけではない。自信を持つのに十分なテストを書くだけだ」と言いました。そこで、ケントと私がプロダクションコードの行ごとにテストを書いたかどうかを尋ねました。
ケントは「状況による。それは、興味深い質問への私の答えの始まりになるだろう」と答えました。 JUnitでは、テストファーストに非常に厳格であり、その結果に非常に満足していました。そのため、TDDを使用しても常に過剰なテストが発生するとは限りません。 ハーブ・ダービーは、デルタカバレッジという概念を考案しました。これは、このテストが提供する独自のカバレッジは何ですか?デルタカバレッジがゼロのテストは、何らかのコミュニケーション目的を提供しない限り、削除する必要があります。 彼は、システムテストを書き、それを実装するためのコードを書き、少しリファクタリングし、最終的に最初のテストを破棄することがよくあると言いました。多くの人がテストの破棄にパニックを起こしますが、それが何も買ってくれないなら破棄するべきです。 同じものが複数の方法でテストされている場合、それは結合であり、結合にはコストがかかります。
過剰にテストされたコードが存在するのは確実だと述べました。もし誰かがそうするなら、Thoughtworksでしょう。なぜなら、当社は強いテスト文化を持っているからです。ちょうど良い量を見つけるのは難しいです。時には過剰になり、時には不足します。時々過剰になることは想定しており、あまりにも大きくなければ心配する必要はありません。 全てのコード行をテストするという点については、「このコード行を間違えると、テストは失敗しますか?」という質問をしました。 意図的にコード行をコメントアウトしたり、条件を反転させたりして、テストを実行し、1つが失敗することを確認することがあります。 私のもう一つのメンタルテスト(Kentからのもの)は、壊れる可能性のあるものだけをテストすることです。 ライブラリは(本当に奇妙なものでない限り)動作すると仮定します。ライブラリの使用を間違える可能性があり、その間違いの結果がどの程度重大であるかを考えます。
Kentは、テストコードの行数とプロダクションコードの行数の比率は、無意味な指標だと宣言しました。 彼にとって形成的な経験は、Christopher Glaeserがコンパイラを書いているのを見ることでした。彼はコンパイラコード1行につき4行のテストコードを持っていましたが、これはコンパイラが多くの結合を持っているためです。より単純なシステムであれば、比率ははるかに小さくなります。 Davidは、コード行をコメントアウトすることを検出するには、100%のテストカバレッジが必要であると述べました。何が壊れる可能性があるかを考えることは探求する価値があります。Railsの宣言的なステートメントは、テストする価値のあるほど多くの破壊を引き起こさないので、彼は100%未満のカバレッジでも快適です。
私は「コードを自信を持って変更できない場合は、テストが不足している(または十分に良いテストではない)」と答えました。そして「過剰な兆候は、コードを変更するたびに、コードを変更するよりもテストを変更する方が多くの労力を費やすと感じる時です。」 ゴルディロックスゾーンにいることが理想ですが、それは自分とチームがどのような間違いをしがちで、どれが問題を引き起こさないかを経験から知ることによって得られます。 状況が不明なときは、「コード行をコメントアウトできるか」というアプローチが好きです。これは出発点ですが、ある環境でより多く作業するにつれて、より良いヒューリスティックを考え出すことができます。 Davidは、この調整は、コードを未知のチームに引き渡すコンサルティングチームではなく、安定したプロダクトチーム間で異なると感じています。そのため、より多くのテストが必要です。 Kentは、テストファーストの規律を学ぶことは良いことであり、開発の難しい部分のための4WDローギアのようなものだと述べました。
Davidは次の問題を紹介しました。多くの人は以前、ドキュメントはコードよりも重要だと考えていました。今では、人々がテストを機能コードよりも重要だと考えていることを心配しています。これと関連して、TDDサイクルのリファクタリング部分の強調不足があります。これらすべてが、リファクタリングとコードの明確さを維持するためのエネルギー不足につながります。 Kentは、テストを保持して再実装しながら、プロダクションコードの一部を破棄したエピソードを経験したと説明しました。彼はそのアプローチを本当に気に入っています。なぜなら、テストによって新しいコードが機能しているかどうかがわかるからです。 これは興味深い質問につながります。コードを破棄してテストを保持するか、その逆か、どちらが良いでしょうか?状況によっては、その質問に対する答えは異なります。
テストを読むことでコードの動作を理解できた状況があったと述べました。どちらが重要かとは考えていませんでした。ポイントは、エラーが発生した場合に不一致が生じる二重チェックです。 Davidの意見に同意し、チームがテスト環境にユーザーサポートよりも多くのエネルギーを費やすという悪い動きをしていると感じることが時々あると述べました。テストは目的を達成するための手段であるべきです。 コードを明確にするとドーパミンが分泌されますが、最大の興奮は、機能を追加する必要があり、難しいだろうと思っていたものが簡単に実現できたときです。これはクリーンなコードのおかげですが、コードのクリーンアップとドーパミンの分泌の間には距離があります。 Kentは、Jeff Eastmanからのこのメタファーを示しましたが、テキストで説明するには複雑すぎます。彼は大きな設計の簡素化から興奮を得ました。 新しいテストが機能することの価値を説明するのは簡単ですが、設計をクリーンアップすることの価値を述べるのは難しいと感じています。
Davidは、私たちはしばしば定量化できることに焦点を当てていますが、設計品質を数値に減らすことはできないと述べました。そのため、人々はテスト速度、カバレッジ、比率など、リストの下位にあるものを優先します。これらのものはハニートラップであり、その魅力的な呼びかけに注意する必要があります。 Cucumberは本当に彼の怒りを買います。テスト環境の美化ではなく、プロダクションコードの美化です。非技術的な利害関係者とテストを作成するという、かなり架空のスイートスポットでのみ役立ちます。 かつてはTDDを販売することが重要でしたが、今ではすべて征服したので、その欠点を調査する必要があります。 TDDが優勢であるという意見には同意しません。多くの場所でまだ普及していないと聞いています。
さらに読む
- 測定値の誤用に関するトピックについては、Pat Kuaの記事「メトリクスの適切な使用」をご覧ください。
- テストカバレッジの使用と誤用についてさらに書いています。
5: 質問への回答
2014年6月4日
視聴者からの質問に答えます。TDDのオープンソースの例、TDDの使用を変えるような変更、経験の浅い開発者にとってどの程度うまくいくかなどです。最後に、TDDの健全性に関する私たちの意見をまとめます。
詳細…
議事録
最初に、視聴者から提出されたいくつかの質問を選んで回答することにより、このハングアウトを構成すると述べます。Davidは、Mike Harrisからの質問を選びます。Mike Harrisは、TDDを使用したオープンソースプロジェクトの例で、テストによって誘発された設計上の損害を受けたもの、またはTDDをうまく使用したものについて尋ねています。Davidは、良い例がなく、これがこの種の議論の問題の1つであると答えます。 一般的に、良いアプリケーションの例はありません。なぜなら、オープンソースの貢献者は、しばしばプライベートアプリケーションやオープンソースの共通フレームワークやライブラリに取り組むからです。 その結果、私たちは異なるコンテキストでこれらの議論に入ります。 そのため、実際よりも多くの意見の相違があるように見えることがよくあります。実際のコードではなく哲学的な原則の場合、人々は集まります。 私たちが持っているコードの例は、人々が実際に作業しているものというよりも、マイナーな例です。 そのため、プレゼンテーションを通して人々を理解する必要があります。そのため、彼は設計上の損害のためにJim Weirichの例を使用しました。良いRailsコードについては、標準的なテストアプローチを示すRailsの本を提案しています。
実際のコードを理解するには多くの努力が必要だとコメントしました。コードベースを掘り下げていますが、時間がかかります。それでも、チームと協力して得られる理解と同じではありません。 Kentは、JUnitが厳密にTDDを使用し、うまくいったプロジェクトの例であると言っています。 しかし、これは明確なインターフェースを持ち、TDDにとって最適なスイートスポットを持っているため、この議論には良い例ではありません。ここでは、さまざまな種類のアプリケーションについて話しています。 良い例があれば、それを書き上げてください。
Davidは、私のコメントは、プログラミングを科学として扱うことができないことを示していると述べています。私たちは客観的に技術を評価することはできません。 これは議論する価値がないという意味ではありません。決定的な答えを得ることはできません。何が理にかなっているかを見極めるのはあなたの仕事です。 Kentは、実験を再現することはできないことに同意しますが、それでも科学的な考え方で個人的に見ることができます。私たちは自分自身で経験的に物事を試すことができますが、普遍的な答えを得ることはできません。
Kentは次の質問(Graham Leeによる)を選びます。KentとMartinにとってTDDを冗長または時代遅れにするためにソフトウェアの書き方について何が変更される可能性があり、DavidにとってTDDを有用にするためにTDDの実行方法について何が変更される可能性がありますか? Kentは、彼のRIP TDDの投稿が彼の立場を示している(やや皮肉な表現で)と答えています。TDDは、自信から始まるいくつかの問題を解決します。 TDDは、彼に問題を少しずつ分解し、一度に一般ケースを解決する必要なく、特定のケースに取り組むことを可能にします。 彼は、難しいからといってTDDを諦める準備はありません。
私にとっては、TDDを時代遅れにする変更ではなく、さまざまなコンテキストにおけるTDDの適用可能性についてです。機械的な方法でTDDに従い、穏やかな「急いでいない速さ」で良いデザインに偶然たどり着いた経験があります。 最近の私のプログラミングのほとんどは、私のウェブサイトのツールチェーンであり、部分的な進歩を行い、優れた回帰テストスイートを持っていますが、TDDは適用できませんでした。しかし、infodeckコードを構築したとき、TDDが効果的だったアプリケーションの動作がたくさんありました。 「いくつかのコンテキストはTDDに非常に適しており、いくつかのコンテキストはそれほど適していません」。そして、人々は自分の個性をそのコンテキストにもたらします。
Davidは、彼の経験も同様であると言いました。彼のテストへの導入はTDDを通してであり、彼はそれを気に入り、すべてに適用しようとしましたが、徐々にMVCウェブアプリケーションの多くの領域ではTDDがうまくいかないことに気づきました。 これは、TDDがいくつかの状況では効果的ではないという意味ではなく、彼の仕事のほんの一部のケースであることを意味します。 しかし、TDDを放棄するということは、自己テストコードを放棄したいという意味ではありません。それは彼にとって常にTDDの価値でした。
これがまさに誰かがTDD(または任意の技術)に取り組むべき方法だと述べました。試してみて、使いすぎて、自分に合ったモードに落ち着きます。そして、もう少し深く見てみましょう。「tddは自己テストコードへのゲートウェイ・ドラッグです」。 Kentは、この種のプロセスを行った後、人々がワークフローでどこに着地しても気にしないと述べました。彼のTDDの使用経験はDavidの経験とは異なります。彼は、開発の中で何かが難しいと感じ、物事を簡素化する特定のプロトコルを持つオブジェクトのアイデアを思いつく瞬間があると彼は感じています。 TDDは、そのようなアイデアに関するフィードバックを迅速に得るメカニズムを提供し、APIの使用例を試して実装します。 彼はまた、TDDが合わないケースも見つけます。その後、command-Rがフィードバックを得る良い方法であることがわかります。 しかし、彼は簡素化するオブジェクトを見て、TDDで試せる瞬間を待っています。
次の質問(Tudor Pavelによる)を選びます。TDDは経験の浅い開発者とどのように機能しますか?私は、TDDは人々に小さな部分を実行させ、インターフェースと実装を分離するのに役立つと答えます。経験なしに良いデザインをすることはできないため、素晴らしい結果を保証するわけではありません。 経験の浅い人がTDDを行うと、通常は十分なリファクタリングを行わず、最適でないデザインにつながります。経験の浅い開発者の出力と経験豊富な開発者の出力を比較することはできません。TDDなしでその経験の浅い開発者が行ったであろうものと比較する必要があります。これは測定できませんが、有利であるように見え、自己テストコードベースを作成します。これは、後でリファクタリングによって改善しやすいためです。したがって、TDDは良い出発点を与えてくれます。
デイビッドは、TDDから得られた価値だと述べました。彼はTDDから始め、素晴らしい補助輪だと感じましたが、それ以降、議論が進まなかったと感じています。 彼は、初心者にシンプルで直接的な、大げさなアドバイスをしなければ、彼らはそれをしないと言う人々には懐疑的です。それは、あなたが教えているものへの自信の欠如を示しています。 私は、そのような独断的な発言への嫌悪感に同意しました。私が説明しているものに対して反論を見つけられないと、私は疑念を抱きます。しかし、一つの例外として、私たちは初心者のために導入的な話を繰り返し続けなければなりません。基礎を繰り返すことに抵抗する人もいます。
デイビッドは、これが私たちが今この会話をしている理由だと考えています。人々がTDDについて説明する際に、基礎に独自の解釈を加え、10年経つと、出発点からかけ離れた、良いとは言えない場所にたどり着きます。 粗野だが効果的な、リセットボタンを押す必要があります。彼がTDDは死んだと言うとき、彼はこの現在の変異を指しています。私たちは第一原理に戻らなければなりません。 ケントは、デイビッドの最初の基調講演に対する彼の最初の反応は、そのレベルにあったと言いました。プログラマーはしばしば同じことを何度も行い、物事を複雑にしすぎ、職場の機能不全なシステムに固執します。彼は第一原理にリブートすることに賛成ですが、過去10年間のプログラミングに対する人々の期待の進化を失いたくありません。自信を持って、進歩を示し、生産的な技術的な協働を行うことができるはずです。彼は、キャリアを始めた頃にはできなかった方法で、今では仕事で自分自身を完全に表現できると感じています。
デイビッドは、TDD、XP、そしてRubyが同時にいくつものものが一緒になったと考えています。プログラミングは楽しいものであるという考えに人々は笑いましたが、彼はRailsの開発においてその考えを続けたいと考えました。今では、Rubyの世界ではその幸福が当然のことだと考えられています。これらのものは、アジャイルと同様に成功しました。 私は、アジャイルが勝利したということに同意しません。ラベルが勝利しましたが、多くの人がアジャイルを行っていると主張しながら、実際には行っていません。これは、私が意味拡散と呼ぶプロセスのようなものによく見られることです。大きな勝利は、今ではクライアントでアジャイルを公然と行うことができるようになったことです。 デイビッドは、他のものにもこのリブートの問題を観察しています。10年後には多くの粗悪品が生まれます。彼はPinkberryの例を用いて説明しました。Pinkberryは当初2つのフレーバーしかなかったのに、他のアイスクリームのように複雑なフレーバーの範囲を持つようになりました。 「ほとんどの人は良いアイデアをそのままにしておくことができません。」 TDDとアジャイルは、今では非常に広範囲な概念です。アジャイルを行っていると主張する人々は、反対のことをしています。 ケントは、デイビッドが経験したようなTDDの問題を見ていません。彼は常に自分の仕事で第一原理からTDDを適用しています。
ケントは、デイビッドがTDDに付着したフジツボに注意を向け、スクレイピングが必要であることを指摘してくれたことに感謝しています。 デイビッドは、Railsでも同様の問題を見てきました。彼は基本的な形式でRailsを使用しており、彼が見てきたいくつかのRailsの使い方にショックを受けています。 ケントは、XPが注目を集めた最初のOOPSLAを覚えています。ジム・ランボーは、10年後にはXPがどう変化するかは認識できないだろうと言い、彼は正しかったのです。 私は、これが成功の姿であり、別の選択肢は物事がうまくいかないことだと述べました。何か悪いことが起きたのが、技術固有の欠陥によるものなのか、技術の誤用によるものなのかを判断するのは常に困難です。私たちができることは、基礎と良い教訓を繰り返し続けることだけです。 デイビッドは同意しました。「あなたは英雄として死ぬか、悪役になるかだ。」 Rubyは、プログラミングに関する良いアイデアのリブートでした。関数型プログラミングも別のリブートです。これらのリブートは健全です。 彼は、RailsとTDDがこれほど長く続いたことに感銘を受けています。 Rails以前はPHPで作業していました。うまく使えばPHPで良いコードを書くことができますが、他の言語の方が良い使用方法を促すことができると感じています。彼は、MVCウェブアプリでTDDをうまく使うことは、クリーンなPHPを書くよりも難しいと考えています。
ケントはそれを経験していません。彼が問題の一部を便利な抽象化に分割できる時はいつでも、TDDを使用できます。 彼は、自分自身をプログラミングに完全に投入するという大きな目標への他の道を探求したいと考えています。彼は実験を通してこれを探求し続けます。やりすぎたり、足りなかったり、ちょうど良い状態を見つけ、その理由を理解したりします。 彼はデイビッドに強く反論して結論づけます。TDDは死んでいませんが、デイビッドがそれに火をつけ、不死鳥のように蘇らせることができてよかったと思っています。
デイビッドは、TDDが効果的ではなかったケースについて人々が話さなかったため、この議論を始めました。彼らは良い気分や自信を感じていませんでしたが、TDDを使用しなければならないと言われました。彼は、TDDがいつ適切でいつ不適切なのかを議論できるよう、許容される反応の範囲を広げたいと考えています。 インターネット上ではTDDの素晴らしさについて語る人がたくさんいますが、人々はそれがうまくいっていないとは言えませんでした。デイビッドにとって、赤ちゃんは自己テストコードであり、TDDに疑問を呈する際にそれを失いたくありません。
私は、(開始前に予想していたように)私たちには多くの共通点があると結論づけて言いました。私たちは皆、自己テストコードを非常に高く評価しており、TDDがいくつかの状況で価値があることに同意しています。私たちはそれがどのくらいの状況で価値があるかについては意見が異なるかもしれません(実際には判断するのが難しいですが)。 すべては、ソフトウェア開発に関わっているなら、それについて考え深くある必要があり、あなたとあなたのチームに合ったプラクティスを構築する必要があり、盲目的にどの技術にも取り組むことはできないという点に帰結します。試してみて、使いこなして、使いすぎて、あなたとあなたのチームに合ったものを見つける必要があります。私たちは体系化された科学の中にいるわけではないので、自分の経験に基づいて作業する必要があります。

この会話に参加するには、#isTDDDeadハッシュタグを使ってツイートしてください。
これらの議論すべてに音声を追加し、Thoughtworksポッドキャストフィードに追加しました。itunesまたはsoundcloudから入手できます。
このビデオがお気に召したなら、バドリ・ジャナキラマンとのこの会話もお楽しみいただけるかもしれません。六角形アーキテクチャ、Active RecordとData Mapperのどちらを使うか、Railsをプラットフォームとして扱うか、コンポーネントのスイートとして扱うかについて詳しく説明しています。
このサイトには、テストとRubyに関する記事が他にもあります。
会話の議事録を含むこれらのページは、韓国語に翻訳されています。