なぜアジャイルがテスト駆動開発(TDD)であり、開発駆動テスト(DDT)ではないのですか?


74

したがって、アジャイルは初めてですが、テスト駆動開発ではありません。大学の私の教授は、テスト、コード、そしてテストのアイデアについてすべてでした。理由がわかりません。私の観点からは、多くの初期費用であり、おそらくコードが進化するにつれて変更されるでしょう。

これが私がTDDを想像し、それが私を混乱させる理由です。TDDの請負業者として家を建てる場合。

  1. すべての仕様(ストーリー)を教えてください。

  2. 仕様の承認を取得します。

  3. すべての仕様を検査に分解します(今後参照してください)。

  4. 検査官に電話してそれらの点を見て、今私は検査に失敗していると教えてください(ありがとう)。

  5. 家を建て始めます。

  6. インスペクタを毎日コールバックします(2/100を渡します)。

  7. ああ、私の理解に問題があったので、今度は9つの検査を追加して、27を変更する必要があります。

  8. 1/109を渡すインスペクターを呼び出します。

  9. 畜生。なぜインスペクターはこのようなものではないのでしょうか...ああ、そのメソッド名を更新しました...

  10. さらにビルドします。

  11. UGGGGHHHHのその他の変更により、いまいましいインスペクタを更新できます。ああ、私は失敗していません。

  12. もう終わった?

さて、それは奇妙なことかもしれませんが、すべてのメソッドをどのように知るべきか、そしてコードがそこに来るまでどのように機能するかはわかりません。99%の時間、戻ってユニットテストを更新する必要があります。ただ逆に思えます。

より適切と思われるのは、DDTまたは開発主導のテストです。これは、コミュニティが忘れてしまったことのように思えます。

私の理解では、家のDDTは次のようになります。

  1. すべての仕様(ストーリー)を教えてください。

  2. 仕様の承認を取得し、それらを分割します。

  3. ユニット(基礎)を開始します。

  4. トリッキーなロジックのメモ(コメント)を取ります。

  5. 最後に次のユニットの検査を開始します(テストを作成します)。

  6. 見つかった問題を修正し、再度検査します。

  7. このユニットが次のユニットに移動することを承認しました。

私たち全員が正直であるならば、それはより人間的で、開発者とビジネスに集中しているとは思わないでしょうか?変更をより速く行うことができ、オーバーヘッドなしでTDDが作成されるようです。


60
私にとって明白な切断は、テストをパスし始めるコードを書く前に、100以上のテストに失敗する可能性があるという考えです。@Telastynが言うように、一度に失敗するテストは数回しかありません。「テスト、コード、テスト」は、コードを書く前にアプリのすべてのテストを書くことを意味しません。
エリックキング

33
比phorはアンチパターンです!人々は、あなたの実際の懸念に対処するのではなく、あなたの比phorが主題に合わない理由を説明するのにより多くの時間を費やすでしょう。この場合、あなたの実際の懸念は、すべてのテストを前もって書かなければならないと考えることです。
ジャックB

21
ここでの補足として、TDDはアジャイルプロジェクトで一般的に使用されますが、アジャイルプロジェクト管理とアジャイル開発プラクティスを区別することが重要だと思います。2つの間に非常に強い関係はありません。プロジェクトの方法論に関係なく、ほとんどのアジャイル開発プラクティスを使用でき、その逆も可能です。アジャイルは、中核をなすものであるため、実際に必要なアプローチを適応させて最良の結果を達成することであり、実行する必要がある規範的なリストではないことを忘れがちです。つまり、アジャイル!=スクラム+ TDD。
ジミージェームズ

35
記録として、ソフトウェア開発と家を建てることを比較することは無意味です。研究が行われました。結果は次のとおりです。答えは明らかです。単に家を建てるのと同じ方法でソフトウェアを構築しないでください。。二。あります。違う。
riwalk

14
アジャイルは、すべての高速フィードバックループについてです、TDDは、フィードバックループのひとつの特定のタイプである
JK。

回答:


83

TDDアプローチの利点の1つは、緊急設計も行う場合にのみ実現されます。

したがって、最初の例えでは、100個のテストを書くことはありません。ソフトウェアがどのように見えるかを知る方法はないからです。

1つのテストを記述します。実行します。失敗します。テストに合格するには、コードの最小単位を記述します。次に、テストを再度実行します。通ります。

次に、上記のプロセスを繰り返して、次のテストを作成します。

これは、コードの意図が明らかな最初の段階では無駄なアプローチのように思えるかもしれませんが、このアプローチの優れている点は、テストカバレッジが常に高く、コード設計がこのようにすっきりしていることです。

方法として、ペアプログラミングと連携します。1つのペアがテストを記述し、次のペアがコードを記述して合格させ、次に次のテストを記述します。

新しいクラスを作成するときに、このアプローチを使用します。最初のテストは、クラスコンストラクターを開始する呼び出しです。しかし、クラスをまだ作成していないため、失敗します。次に、単純な空のクラスを作成し、最初のテストに合格します。

いったん考え方に慣れると、そこに入らずに「昔ながらの」方法でコーディングすることは非常に困難です。

これを学ぶには、優れたアジャイル環境で作業するか、または理解を深めるためにいくつかの優れたアジャイル本(Clean CodeとClean Coderはどちらも非常に優れています)を読むことをお勧めします。


46
「Emergent Design」という用語は、テストに合格することでソフトウェア設計を成長できるように聞こえます。できません。
ロバートハーベイ

28
@nerdlyist:しかし、デザインを忘れないでください。それでもソフトウェアを設計する必要があります。優れたデザインは、赤緑リファクタリングから自然に生まれるだけではありません。TDDは優れたデザインを奨励しますが、それを作成しません。
ロバートハーベイ

19
@RobertHarvey、あなたの「Emergent Design」という用語は、テストに合格することでソフトウェア設計を成長できるように聞こえます。何度もそれをやったことがありますが、私はそれができることを保証できます。
デビッドアルノ

12
@DavidArno:手元の要件仕様から始めますか?その仕様を賢明なアーキテクチャにどのように変換しますか?テストを行うたびにそれを再発明しますか、または以前のアーキテクチャの原則を念頭に置いていますか?ブラインドでこれを行う人はいません。最初にテストを書くことについて、魔法のようなことは何もありません。コードをテストしやすくすることを強制する以外は何もありません。
ロバートハーベイ

45
@DavidArnoあなたの反対は、経験豊かな開発者/建築家として十分な信用を与えていないことに起因すると思います。モジュールXが直感的にどのように見えるかをすでに知っているので、テストは開発を良い方向に進めるでしょう。テストを作成する前にモジュールがどのよう見えるべきかについての直感的な概念をほとんど、またはまったく持たない経験の浅い開発者は、十分にテストされたくだらないモジュールを構築します。
svidgen

86

ソフトウェアは家ではありません。直感は良いのですが、必ずしも正しいとは限らないことを理解してください。

すべての仕様を検査に分解します(今後参照してください)。

これは正確ではありません。TDDでは、コードの使用方法を説明しています。仕様書には、「そこに入る方法のある家がなければならない」と書かれています。テストでは、「ねえ、ノブが付いた玄関が欲しい」と言います。これは、ドアフレーム、ノブ、キーロックなどの構築の実装から開始するよりも、将来を見通すことははるかに少なくなります(または議論が進みます)。

インスペクタを毎日コールバックします(2/100を渡します)。

これは正しくありません。あなたは家のためのテストを書いていません。あなたはフロントドアフレームのテストを書いて、それをグリーンにします。次に、ドアがしっかりしていることをテストして、緑にします。あなたは持っている必要があり、おそらく、せいぜい任意の時点で破断ダースかそこらのテストを。通常、2〜4に近いです。

また、「検査官を呼ぶ」という例えは、人が出て仕事をするのにある程度の時間がかかることを意味します。TDD反復の単体テストの実行には、文字通り数秒かかります。

変更をより速く行うことができ、オーバーヘッドなしでTDDが作成されるようです。

オーバーヘッドは、あなたが暗示しているように見えます。テストを実行するのに数秒かかることは、全体の開発時間には重要ではありません。

最初にdevの問題になるのは、テストを開始するときに、大きな問題があることがわかったときです。トイレの隣にベッドを置いて、そこに住みたい人はいません。あらゆる種類のTDDオーバーヘッドよりも修正に時間がかかるもの。TDDは、最初からコードを使用し、それとのインターフェイス方法について考えることを強制するため、TDDがキャッチするはずのもの。

大学の私の教授はすべて、テスト、次にコード、テストのアイデアについてでした。

とは言うものの、TDDはそれほど一般的ではありません。多くの場所がまだ最初に開発を行っており、TDDの利点の多くは誇張されています。重要なのは、テストを作成し、それらを適切に作成することです。作業を行う順序はそれほど重要ではありません。


18
最後の段落だけに+1。あなたの家の例は、本当に「religiousTDD」がどれほど愚かであるかを強調しています。
ロバートハーベイ

23
「重要なのは、テストを作成し、それらを改善することです。作業の順序はそれほど重要ではありません。」私はテスト駆動開発(TDD)の大ファンであり、それを頻繁に支持しています。しかし、コードを書くのは面倒です。より困難で、あまり明確ではない問題については、通常、最初にいくつかのコードを書いてから、要件を理解する必要があります。その後、要件を作成してからテストを作成できます。
トレバーボイドスミス

1
@TrevorBoydSmithは、要件ではなく、その時点でドキュメントを書いているのではないでしょうか。
オタクリスト

8
TDDはコードのユーザーの観点に置かれるため、[ベストケースでは]より良いインターフェイスを促進します。たとえば、私が電話するときopen_door、フラグを渡す必要はありませんtoilet_flushed; そのため、テストをそのように記述しないため、コードにはこれらの「粗いエッジ」がありません。呼び出される方法を十分に考慮せずに完全に記述されたコードには、奇妙なインターフェイスや前提条件があります。
brian_o

3
@TrevorBoydSmithに名前を付けると、「スパイクと安定化」と呼ばれることを聞いたことがあります。はい、まだ方法がわからないことをする方法を発見するときに便利なテクニックです。
ラバーダック

13

物理的なものを作成することとソフトウェアを書くことの類似点はごくわずかです。

ただし、指摘する価値のある大きな違いが1つあります。

「テストの作成」と「テストの実行」には違いがあります。

家を建てる例では、要件とテスト物理的なビルドアウトの前に行われます。また、テストスイートの一部は、複数のエージェントでも継続的に実行されます!ビルダーが2x4を拾い上げると、彼はすぐにそして自動的に「2x4の音がどのように見えるか」という概念に対してユニットを「テスト」します。彼はそれを選択した後、要件を作成しません。彼は既存のチェックを実行します。

同様に、組み立てられた壁、電気ボックス、配管などにも、テスト/要件がすでに存在します。彼らは仕事の全員の訓練された目によって暗黙的かつ自動的に継続的に実行されます。検査官が訪問すると、既存のテストの別のスイートが実行されます。ユニットがこれらの既存のテストに合格するように構築されていない場合、それらは失敗します。

同様に、構造全体についても同様です。計画にはビルドアウトが既に存在します。方法のあらゆる段階で、エンジニアは、ビルドアウトが完了したときに構造が最終的にテストされる既存の条件のセットに向かって取り組んでいます。

とは言っても、すべての物理プロジェクトの前に膨大なテストを行う必要はありません。ワークショップに行って、おもちゃ箱などのために木材を組み立て始めて、直観力と創造性があなたを導いてくれるなら、それは厳密なTDD木工ではありません。その場合、基本的には媒体の物理法則と大まかな期待に基づいて作業を検証します(つまり、「コンパイルして正常に動作する場合、それは良いことです!」)。

そしてそれは大丈夫です。厳密なテストをすべての前に行う必要はありません。

tl; dr

構築!=ライティングソフトウェアの場合:構築はテスト駆動方式で動作します。すべてのユニットのための「合格」の条件が行う彼らのビルドアウトの前に。

「テストの実行」と「テストの作成」を混同しないでください。

すべてがTDDである必要はありません。


私はコードを取得します!=物理的なそのアナロジー。しかし、これは実際にはもう少し明確になります。私の他のコメントが指摘しているように、このテストを最初に作成すると、今すぐ戻ってより大きな変更を加えたいという欲求が妨げられるのではないかと思いますか?
オタクリスト

@nerdlyistある意味、はい。しかし、テストが「正しい」ことをチェックしている場合、それはあなたが望む「障害」です。
svidgen

4
家の例えに戻って:もしあなたのクライアントが突然異なるスタイルのドアに交換したいと思って、それが同じ寸法を持っていなければ、ドアと開口部の寸法の要件は変わり、仕事はそれらの「テスト「実装の変更に必要な作業を反映する必要があります。しかし、変更されないテストはたくさんあります。ドアは開閉し、ロックし、閉じたときに開口部の気密性を確保する必要があります。など。その「障害」を変えない多くのテスト適切な身体的変化。
svidgen

1
もう一度+1できたら、その最後のビットを考慮すると便利です。すべてがテストを必要とするわけではありません。また、それを読み直したことで、TDD単体テストと統合テストおよび回帰テストを融合しているのかもしれません。自動的にテストするワーカーは、インスペクターが統合する単位であり、大きな変更を加える場合は回帰テストが行​​われます。
オタクリスト

1
@nerdlyist統合および回帰テストは、テストファーストでも実行できます。そうすることは「TDDドッグマティスト」の開発サイクルに完全には適合しませんが、結果はほぼ同じです。テスト可能なコード、最小限の無関係なコード、および彼らが主張するものを実際に検証するテストになります。コードを書いた後のテストは、これらのことの一部またはすべてを達成するのを少し難しくする可能性があります。まったく不可能ではありませんが、潜在的にはより困難です。
-svidgen

11

ソフトウェアを書くことは家を建てることに似ているというナンセンスな考えを信じるというlieに陥りました。そうではありません。これは、建築家の図面と構造エンジニアの計算を作成することに似ています。

現在、実際の家で、建築家はそれらの計画を前もって作成します。次に、建築者を呼び出します。建築者は、建築を開始し、問題に遭遇し、物事を修正し、建築管理を取得し、変更を希望します。どうした。これは物事を行う安っぽい方法ですが、家は建てるのに長い時間がかかり、高価なので、それが唯一の実用的な方法です。

物事はソフトウェアエンジニアリングにとって優れています。家を建てるのと同じことは、コンパイラーがコードをある種のコンパイル済みユニット(ライブラリー、アプリ、Webアプリなど)に変換することです。これを1日に数百回行うのは非常に高速で安価です。そのため、機能を追加するときに家を繰り返し再構築し、最後にインスペクター(QA)を呼び出してテストするだけでは意味がありません。代わりに、これらのチェックを自動化する場合、再構築するたびにインスペクターにすべてを再検査させることができます。

厳密なTDDに従うか、いくつかのコードを作成するというよりテスト指向のアプローチに従うかは、実際には重要ではありません。私は最初のアプローチを好み、他のアプローチは後者を好みます。あなたに合ったものを選んでください。重要なことは、あなたが進むにつれてそれらのチェックを作成することです。後でコードを変更したいときに、何かを変更したときに他の場所で機能の中断を警告することで役立ちます。


1
ビル管理に対処したことがわかります。...)
ジュール

5
「これは物事を行う安っぽい方法ですが、家は建てるのに長い時間がかかり、高価です。それが唯一の実用的な方法です。」:ソフトウェアでは、非常に迅速に再構築できますが、完全に間違った場合最初の決定は、後で大幅な書き換えが必要になる場合があります。インクリメンタルデザインは、この種の問題を常にキャッチするとは限りません。クルドサックに自分自身を見つけて戻る必要があるまで、少しずつ移動します。特効薬はありません。
ジョルジオ

2
@Giorgio-単一の決定がコードの多くの場所に反映されるため、大きな書き直しが行われます。決定が変わると、コードは多くの場所で変わります。継続的なリファクタリングは、重複を絞り出し、単一の決定を反映するコードの量を制限することにより、この問題を軽減します。優れたテストカバレッジは、継続的なリファクタリングをサポートします。
ケビンクライン16

7

何よりもまず、初期費用はあなたが思っているほど高くありません。はい。テストを行わない場合よりも、テストに対処するのに時間がかかります。しかし、「テスト後」メソッドを実行すると、実際に何が無駄になりますか?TDDに10時間かかり、DDTに6時間かかるとします。「追加の」初期費用はわずか4時間です。コードメトリックまたは90%カバレッジなどの要件を適用すると、TDDとDDTのコストがさらに近くなります。

TDDを使用すると、バグの少ないコードを記述できます。テストとして要件を詳しく説明したからといって、1日の終わりに、コードが意図したとおりに動作していることを証明できます。おそらく、あなたはそれが間違ったことをしたかったのかもしれませんが、それは変更要求であるバグではありません。これは重要。動作している製品を「販売」するのは簡単ですが、異なる/より良い動作をする可能性があります。次に、動作していないと思われる製品を販売することです。TDDでは、テストに合格して動作しないコードを書くことは文字通り不可能です。要件を理解していない可能性があり、間違っているが動作するコードを書いている可能性があります。

TDDは、コードベースが古いほど優れています。テストスイートなしで、または実装が不十分なリファクタリングを試してください。簡単な変更でもバグが発生する可能性があります。カバレッジが良好なテストスイートを用意することで、製品が進化しても機能し続けることが保証されます。また、競合するビジネスルール(長期間にわたって発生する)を強調するのにも役立ちます。

あなたはそれが機能しないことを知りません。テストスイートがないと、コードが思ったとおりに動作しているかどうか、または動作しているように見えるかどうかがわかりません。

var foo = function(in) {
    if(in == 0) {
      return true
    }
}

これで、アプリケーション全体で、if(foo()){ doStuff() }fooを修正するとどうなりますか?

var foo = function(in) {
    if(in === 0) {
      return true
    }
}

テストもリファクタリングおよび乾燥する必要があります。優れたテストスイートを維持するのは難しくありません。よく書かれたアトミックテストを使用すると、一度に1〜2個以上戻って変更する必要はほとんどありませんでした。テストスイートに大きな変更が加えられたとき、それは何かが正しくないという大きな赤い旗です。

私は、自分のすべてのメソッドをどのように知るべきか、そしてコードがそこに到達するまで物事がどのように機能するかをただ見ていません。

まあ、あなたはするべきではありません。何らかの作業単位が完了したことをテストするテストを作成することになっています。あなたがおそらく知ることができないものをテストしているように感じるなら、あなたは大きすぎると考えています、またはテストは小さすぎます。

たとえば、ドアが閉じてロックされることを知る必要があります。door.close()とdoor.lock()をテストすると、ドアがロックされるとdoor.open()がfalseを返します。それだ。テストがdoor.lock()の場合、データベースにフラグを設定します。次に、テストが小さすぎます。テストではdoor.lock()がどのように機能するかを知る必要はありません。

ここで、すべてのドアと窓がロックされているときにhouse.isSecure()がtrueを返すというテストを書いている場合。最初にドアや窓を見ないで、大きすぎると考えています。

最後に、大きすぎる作業単位を見ている可能性があります。要件のリストを取得したら、最小単位で作業するように要件を整理する必要があります。そのユニットだけのテストを書き、次にコードを書き、すすぎ、繰り返します。

本質的に、TDDがどのように機能するかについての理解(リスト)はずれています。2/100パスすることはありません。1/1通過、2/2通過、3/3通過、4/4通過などのようになります。

改訂されたリスト

  1. すべての仕様を入手する
  2. 仕様を1つ選択してください
  3. 試して
  4. コーディングする
  5. 試して
  6. テストに合格した場合は7に進み、それ以外の場合は4に進みます
  7. すべての仕様を完了したら、8に進み、それ以外の場合は2に進みます
  8. 消費者と仕様を確認し、必要に応じて新しい仕様を追加します。正しく行われていれば、テストをまったく変更する必要はありません。新しいものを追加するだけです。要件の収集がバラバラになることがあり、以前のテストと競合するテストを追加する必要がありますが、テストを変更する必要はほとんどありません。

2
この回答は、TDDの本当の利点(レガシーコードベースを管理しやすくすること)を強調しているため、気に入っています。プロジェクトのグリーンフィールドフェーズでしか作業していない多くの人々は、TDDが単なる余分な作業のように見えるため、TDDの利点を理解していません。既存のコードベースをアップグレードして保守する必要がある場合、本当に効果があります。学校で彼らがあなたにプロジェクトを提供し、それが機能するようになったらすぐに、たくさんの機能の変更をリクエストしてください。それは現実をより密接に反映し、TDDの価値を実証します。
-thomij

1
私もこの答えが好きです。テストを手動で実行するのに実際にどれだけの時間を費やすかを忘れがちであることに注意してください:編集、コンパイル、ステップスルーによる手動デバッグ、繰り返し。TDDはこの多くを自動化します。
テクノフィル

ここで飛び出しているのは、TDDで単体テストを作成するとき、クライアントの機能仕様の一部のテストを作成するのではなく、あなたとしてのユニット-プログラマー-は、あなたの脳でそれを定義しました。つまり、「このクラスは、Xが発生したときにイベントを発生させるはずです。そのためのテストを書きましょう。」このあいまいな「テストはあなたの仕様です!」すでにTDDを取得している場合、レトリックは素晴らしいですが、ループの外にいる人には、答えよりも多くの質問が発生します。
Ant P

4

他の答えが欠けていると感じるいくつかのキーがあります。

3つの利点

まず、エラーのコストと変更のコストは、ソフトウェアと家の間で非常に異なるため、一部のルールが適用されない場合があります。たとえば、物理構造のテストにかかるコストは非常に高いため、テストを無駄にしないように、構造の動作に高い信頼性が必要です。ソフトウェアを使用すると、1〜5秒で一連の単体テストを実行できる場合、さまざまなオプションを自由に使用できます。

次に、テスト対象コードを記述する前に失敗すると予想されるテストを実行する目的は、テスト自体を検証することです。確かに、それは愚かまたは無駄に思えるかもしれません。しかし、テスト対象のコードが壊れていても、常に合格する方法で記述された十分な単体テストを見てきました。これは、テスト対象コードを作成し、手動でテストしてから単体テストを作成すると簡単に発生します。単体テストを作成する場合、失敗することを確認し、合格するために必要なコードを記述して合格すると、テストが正常であることがわかります。テスト対象のコードが退行した場合、単体テストがそれをキャッチする可能性は十分にあります。

TDDの3番目の利点は、あまり言及されていませんが、結果として生じるコードサイズと複雑さは、しばしば1桁小さいことです。私は常にシンプルで簡潔なコードを好むことに誇りを持っています。TDDの練習を始めるまで。TDDは、以前にやっていたことは過剰なコードになることを示しました。なぜこれが起こるのですか?テストを作成するため、テストに合格するコードを作成します。テストに合格すると、完了です。あなたがこの考え方に沿っているなら、誤って「余分な」コードを書くことは困難です。

(余分なコードは、私が使っていた製品で見た問題でした。誰も要求していないコードに起因する深刻な問題ですが、一部の開発者はそれがクールだと考えました。)

コスト分析

だから、いくつかの点で、あなたは正しい。家を建てるとき、この戦略を逃れられませんでした。それは高すぎます。しかし、ソフトウェアは家ではありません。ソフトウェアは安いです。

家との類推は、家とソフトウェアコンパイラを組み立てる労力です。

非TDDの世界では、開発者は依然として反復しています。コード->コンパイル->実行->テストサイクルに従います。私たちはすでに、家を建てることから大きく逸脱したモデルになっています。建設担当者がドアフレームを構築してからドアを構築し、ドアが大きすぎるためにフレームを再構築する必要がある場合、コストの問題が発生します。したがって、すべてを完璧にするために、より多くの時間を前もって費やします。プログラミングでは、ほとんどのプロジェクトは数秒または数分でコンパイルできるため、初期段階で何かが不完全であるかどうかは関係ありません。通常、前もって些細なことを考えるコストは、再コンパイルのコストを上回ります。したがって、常に再コンパイルします。

TDDも同じ原理で、テストが前に進むように回転するだけです。テストを非常に安くすることができる場合(すべてが数秒で実行されます)、1つのビッグバンコーディングイテレーションで全体像、完璧なソリューション全体を考えるコストがリファクタリングのコストを上回ります。

を除いて...

プログラミングには、これらの引数が保持されないものがいくつかあります。それがアーキテクチャの目的です。後で変更するのに費用がかかるような事前の懸念事項を特定して計画します。たとえば、ニーズを考えずにその場でデータベースを選択し、構築を開始して、後で変更できると主張するだけです。あなたはそれを熟考する必要があります。


1
テストを検証する上で大きなポイントです!また、家を建てるとき、壁を動かすのは難しいです(そして、これは傷を残します)。ソフトウェアを使用すると、コードの移動は比較的簡単です-意図しない変更をキャッチするための自動化されたテストがある場合。
テクノフィル

4

TDDのいくつかのプロジェクトをやるまで、私はこのことについてよく考えていました。私がこれをしている間、私に飛び出した非常に簡潔で包括的な説明があります:

コードを書くとき、コードが何か意味のあることを確認する何らかの方法が必要です。したがって、コードをテストします。アドホックテストを実行できます。しかし、物事を始める前にテストする方法を考えれば、テストはよりうまく機能します。したがって、テストに進む前にテスト戦略を設計します。

テスト戦略について考えているので、少なくともその一部を自動化することもできます。そして、ある程度のTDDがあることに注意してください。テストに合格するまでコードを記述するという事実は正常です。それはとにかくあなたがすることです、それが機能するまでコードを書きます。テストを爆破するのは簡単です。

範囲を超える理由により、すべてを一度に書くことはできません。したがって、テストを一度に設計することもありません。しかし、基本的にはそういうことです。テストの計画を改善するだけで、常にテストを前もって書く必要はありません。進行中にさらに追加して、予期しなかったバグを見つけたり、後でテストをより堅牢にすることがあります。また、テストを設計していないのに手作業でテストするのが面倒で、後でテストを行う場合もあります。

したがって、TDDは、作業を検証する方法を検討する上での極端な方法にすぎません。


4

この質問にはすでに受け入れられた答えがありますが、筆記試験なしの設計スタイル(テスト手順に従って「テスター」が手動で実行するすべてのテスト)からTDDに追加するものがあると思います。これらは私の個人的な観察に過ぎませんが、かなり普遍的だと思います。

あなたが何か新しいこと、あなたが今までにやったことのないことを書いているとき、TDDとTDDをしないことの間に大きな違いはありません。

一般的には、アイデアを調査するための小さなコードを記述し、「テスト」のためにハードコーディングされたビットを追加してから、コンパイルおよび/または実行します。それが機能する場合、ハードコードされたものを削除し、パラメータ、インスタンス変数などを追加してコードを一般化します。

考えてみてください。これは、TDDとまったく同じ量の作業です。唯一の違いはTDDで、「テスト」ビットを別のファイルに個別に書き込み、最後に削除しないことです。TDDでは、テストコードを保持します

もちろん、TDDが少し整理されているということは、実際のコードからコードのテストビットを分離する方法を見つけるためにもう少し作業があることを意味します。ただし、単体テストを書いたことがあれば、テスト用にコードをモジュール化する方法を学習できます。


2

なぜアジャイルがテスト駆動開発(TDD)であり、開発駆動テスト(DDT)ではないのですか?

質問が事実を示唆していることを知っているので、ここでただチャープします(「アジャイルはTDDについてです」)。すべての答えは、この事実を当然のように受け止めているようです。アジャイルが主にTDD(別名、ユニットレベルでのテスト)であると想定する場合、これらは良い答えです。

https://en.wikipedia.org/wiki/Agile_software_development#Agile_methodsには、多数の異なる開発モデルがリストされています。

特に、行動駆動型開発と機能駆動型開発を思考の糧として提供します。完全に別の獣も、基本的なTDDのすべての利点につながる単純な赤-緑-リファクタリングのサイクルからは程遠いですができます。

だから私の答えは:

  • 「DDT」(別名、実装の後または「上」にテストを書く)は、現実の理由では機能しません。時間やお金のプレッシャーがかかるとすぐに、テストは窓から消えます。とにかく、テストを行うことの利益のためにテストをするだけではなく、むしろIMOです。
  • アジャイルはありません基本的には「すべてのビルディングブロック/クラス用のユニットテスト」を意味するものとして、あなたがその用語を解釈する場合には(少なくともウィキペディアによると、ケースである、)すべてのテスト駆動開発(TDD)について。TDDは、アジャイル開発を行う1つの可能性にすぎません。
  • フルスタックアプローチを実行するBDDやFDDなどの他の方法があります。シナリオを前もって記述し、赤緑リファクタリングサイクルがあり、シナリオが緑になるまで実装しますが、定義により「テスト」はソフトウェア全体を実行し(ユーザーインタラクションのように動作する)、単一ユニットのみ。

むしろ、完全な単体テストカバレッジとフルスタックテストのないアプリケーションよりも、完全なBDD / FDDカバレッジと単体テストのないアプリケーションが必要です。

(TDDにはもちろんAPIなどの場所がありますが、それはここで話していることではありません。)

繰り返しますが、私はここで他のすべての答えをダウントークしようとはせず、質問がかなり狭く定式化されており、フィールドにはもっと多くのものがあることを指摘しています。


私は他のことを知っていましたが、この記事を書いている時点では、このddtはもっと意味があるように思えました。TDDがAPIに適している理由を詳しく説明してください。MVCを備えたWebクライアントでそれをどのように使用しますか?
オタクリスト

1
APIでは、非常に詳細な契約に従うことが非常に重要です。各メソッド呼び出しは、ユーザー(他のプログラム)が正しく使用するために非常に予測可能な動作をする必要があります。これがユニットテストが本当に輝くところです。OTOH、アプリケーションでは、人間のユーザーが意図したとおりに機能するために必要な機能にとって最も重要です。もちろん、「内部」も正確である必要がありますが、個々のメソッドをテストするのではなく、「エンドツーエンド」機能(UIからDBへ、そしてその逆)を十分にカバーすることが重要です。とにかく人間のエンドユーザーには表示されません)。
-AnoE

もちろん、ここではすべての度合いが異なります。非常に複雑なメソッド/クラスをどこかに配置する必要がある場合(たとえば、地理座標間の距離を計算する場合)は、ここで単体テストを少し行うことも理にかなっています。ただし、バルク(ビジネスアプリケーションなど)は全体的なワークフローです。
-AnoE

0

このように書かれていることはあまりありませんが、アジャイルの背後にある理由の多くは、コードを書き直す方が初めて書くよりも優れているということです。コードを書き直すたびに、コードを改善し、自分自身を改善します。最初に「正しく」取得することは、より遅く、より脆くなる傾向があります。

家の例えはそれほど悪いわけではありませんが、家の建設について知っている期間とソフトウェア工学について知っている期間について考える必要があります。また、ソフトウェア工学の複雑さは長い橋の建設に近いですまたは家よりも20階建ての塔。また、新しい言語とツールが構築されると、すべての建築者がまったく異なる形状、サイズ、素材で建物を構築したいと考えていることを考慮する必要があります。完全なカオス。

ただし、検査はコードテストの良い例えではありません。ソフトウェアでは、適切な検査官がいるほどではありません(さまざまなスキルレベルの仲間を除きます)。また、おそらくほとんど任意の「コーディング標準」(構造よりもペイントの色や芝生のレイアウトをテストするようなもの)を除いて、検査する規制もありません。

テストファーストは、壁を構築し、壁に持ち上げて家に置く前に安定性を確保するために壁に圧力をかけるようなものです。それは、ウィンドウを測定して、配置する前に残した穴に収まることを確認するようなものです。

何世紀にもわたる以前のアーキテクチャの知識、パターン、規制、および数学を使用せずに一連の橋を建設しなければならなかった場合、橋を建設する前に橋が機能することを証明する必要があります。おそらく、橋をLOTでテストおよび再構築することになります。

最後に、アナロジー以外のポイント-ソフトウェアを使用して、コードのセクションを書き直すことが許可されるたびに、コードとスキルの両方が大幅に向上します。コードを書き直すためにできる限りの機会をとってください。TDDは大きな言い訳になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.