web-dev-qa-db-ja.com

TDDを行うときに、一度にすべてのテストを記述しないのはなぜですか?

TDDの赤-緑-リファクタリングサイクルは十分に確立され、受け入れられています。 one失敗する単体テストを記述し、それをできるだけ簡単にパスさせます。このアプローチを書くことの利点は何ですかmanyクラスの単体テストに失敗し、すべてを一度にパスするようにします。

このテストスイートは、リファクタリングの段階で誤ったコードを記述したり、間違いを犯したりしないように保護しています。場合によっては、最初にクラス(またはモジュール)のすべてのテストを「ブレインダンプ」の形式として書く方が簡単です。

57
RichK

テスト駆動設計とは、コードではなく[〜#〜] api [〜#〜]を正しくすることです。

最初に失敗する最も単純なテストを作成する利点は、API(基本的にはオンザフライで設計している)をできるだけ単純にすることです。前に。

今後の使用(次のテストの記述)は、より複雑なケースに対処する次善の設計ではなく、最初の単純な設計から行われます。

52
user1249

one testを書くとき、あなたはone事に集中します。
多くのテストでは、多くのタスクに注意を向けるので、それは良い考えではありません。

77
Abyx

単体テストを作成する際の問題の1つは、コードを作成していることと、それ自体で潜在的にエラーが発生しやすいことです。また、実装コードを作成する際のリファクタリングの結果として、後でテストを変更する必要が生じる可能性もあります。つまり、TDDを使用すると、テストに夢中になりすぎて、プロジェクトの過程で実装が成熟するにつれて、本質的に「テストされていない」テストコードの多くを書き換える必要が生じる可能性があります。この種の問題を回避する1つの方法は、一度に1つのことだけに集中することです。これにより、テストに対する変更の影響を最小限に抑えることができます。

もちろん、これは主にテストコードの記述方法に依存します。個々のメソッドごとに単体テストを作成していますか、それとも機能/要件/動作に焦点を当てたテストを作成していますか?別のアプローチは、適切なフレームワークでビヘイビア駆動アプローチを使用し、テストを仕様であるかのように書くことに焦点を当てることです。これは、BDD方式を採用するか、より正式にTDDを使いたい場合はBDDテストを採用することを意味します。または、TDDパラダイムに完全に固執し、テストの作成方法を変更して、個別にテストメソッドに完全に集中するのではなく、実装している要件機能の詳細を満たすための手段として、より一般的に動作をテストすることもできます。

あなたが取る特定のアプローチに関係なく、上記で説明したすべての場合において、あなたはテストファーストアプローチを使用しているので、単純に素敵なテストスイートにあなたの脳をダウンロードしたくなるかもしれませんが、あなたはまた、絶対に必要な以上のことをする誘惑。新しいテストスイートを開始しようとするときはいつでも、YAGNIを繰り返し自分自身で開始し、時にはそれをコード内のコメントに投げ込んで、すぐに重要なことに集中し続けることと、実装しようとしている機能の要件。 Red-Green-Refactorを使用すると、これを確実に実行できます。

28
S.Robins

これを行うと、TDDのprocessを見逃してしまうと思います。最初にすべてのテストを記述するだけで、TDDを使用した開発プロセスを実際に経験することはありません。あなたは単にあなたが必要とするテストを前もって推測しているだけです。これは、コードを開発するときに一度に1つずつ行う場合、最終的に作成するテストとは非常に異なるテストセットになります。 (あなたのプログラムが本質的にささいなことにならない限り。)

17
ZweiBlumen

TDDの背後にある考え方は、迅速な反復です。

コードを記述する前に記述する必要がある一連のテストがある場合、コードを繰り返しリファクタリングすることは困難です。

簡単なコードのリファクタリングがなければ、TDDの多くのメリットが失われます。

11
linkerro

「ブレーンストーミング」の最中に、考えられるすべてのテストを「書き」ますが、各テストは1つのテストとして記述しますcommentテストの説明。

次に、1つのテストをコードに変換し、コンパイルして渡すになるように作業を行います。自分がやったと思ったすべてのテストが必要ではないと判断したり、別のテストが必要になったりすることがよくあります。この情報は、テストに合格するためのコードを記述することからのみ得られます。

問題は、テストするメソッドとクラスを作成するまで、コードでテストを作成できないことです。そうしないと、一度に1つのテストに取り組むための多くのコンパイラエラーが発生します。

テストが「英語」で記述されているときに仕様フローのようなシステムを使用している場合、単一のテストを作成するだけでなく、時間がある間に顧客に一連のテストに同意してもらいたい場合があります。

11
Ian

TDDの私の(限られた)経験から、私はあなたに言うことができますevery時間一度に1つのテストを書くという規律を破った、物事はひどく進んだ。それは陥りやすい罠です。 「ああ、その方法は取るに足らないことだ」とあなたは自分で考えています。ええと、何だと思いますか?見た目ほど簡単なものはありません。私がこの罠に陥るたびに、私は考えた簡単なものをデバッグしてしまいましたが、奇妙なコーナーケースがあることが判明しました。そして、私は一度にいくつかのテストを書くことになったので、バグがどこにあるかを追跡するのは大変な作業でした。

情報のブレインダンプが必要な場合は、多くのオプションがあります。

  • ホワイトボード
  • ユーザーストーリー
  • コメント
  • 古き良きペンと紙

このリストのどこにもコンパイラがないことに注意してください。 :-)

5

あなたはそれを書く前にあなたのコードがどのように見えるか知っていると仮定しています。 TDD/BDDは、QAプロセスであると同時に、設計/発見プロセスでもあります。特定の機能について、機能が満たされていることを確認する最も簡単なテストを記述します(機能の複雑さのために、いくつかの機能が必要になる場合があります)。最初に作成するテストは、作業コードがどのようになるかを想定して読み込まれます。それをサポートするコードの最初の行を書く前にテストスイート全体を書く場合、検証されていない仮定の無作法なことになります。代わりに、仮定を1つ記述して検証します。次に、次を書きます。次の仮定を検証するプロセスでは、以前の仮定を破って、最初の仮定を変更して現実に一致させるか、現実を変更して最初の仮定が引き続き適用されるようにする必要があります。

作成する各単体テストは、科学ノートブックの理論として考えてください。ノートに記入すると、理論を証明して新しい理論を形成します。新しい理論を証明すると、以前の理論が反証されることがあるため、修正する必要があります。 20を一度に証明しようとするよりも、一度に1つの理論を証明する方が簡単です。

5
Michael Brown

TDDの1つのパラダイムは、単に1つのことを考えるだけでなく、テストに合格するために可能な限り最小限のコードを記述することです。一度に1つのテストを作成すると、そのテストに合格するのに十分なだけのコードを作成する方法を簡単に確認できます。一連のテストにすべて合格すると、コードに小さなステップで到達するのではなく、すべてを一度に合格させるために大きな飛躍を遂げる必要があります。

ここで、すべてを一度に合格させるためのコードの記述に限定せず、一度に1つのテストに合格するだけのコードを記述しても、機能する可能性があります。ただし、必要以上に多くのコードを書くだけでなく、より多くの規律が必要になります。そのパスを開始すると、少なくともテストによって駆動されないという意味で、テストによって記述されているよりも多くのコードを記述できるようになりますnestedどのテストでも必要とされていない(または実行されていない)と感じてください。

コメント、ストーリー、機能仕様など、メソッドの実行内容を完全に把握できます。私はこれらを一度に1つずつテストに変換するのを待ちます。

テストを一度に作成することで見落とす可能性があるもう1つのことは、テストに合格すると、他のテストケースについて考えるように促す思考プロセスです。既存のテストのバンクがなければ、最後に合格したテストのコンテキストで次のテストケースを考える必要があります。先ほど述べたように、メソッドが何をするべきかについての良い考えを持つことは非常に良いことですが、多くの場合、私はアプリオリとは考えていなかった新しい可能性を見つけることに気づきました。テスト。私がまだ持っていない新しいテストを何と書けばよいかを明確に考える習慣をつけないと、これらを見逃してしまう危険があります。

4
tvanfosson

TDDは非常に反復的なアプローチであり、(私の経験では)実際の開発方法によく適合します。通常、私の実装はこのプロセス中に徐々に形を整えていきます。各ステップで、テストに関するさらなる質問、洞察、アイデアがもたらされる可能性があります。これは、私の心を実際のタスクに集中させるのに理想的であり、限られた数の物をいつでも短期記憶に保持するだけでよいので、非常に効率的です。これにより、間違いの可能性が減ります。

あなたのアイデアは基本的にビッグテストアップフロントアプローチであり、IMHOの方が扱いが難しく、無駄が増える可能性があります。作業の途中でアプローチが良くないことに気づいた場合、APIに欠陥があり、最初からやり直すか、代わりにサードパーティのライブラリを使用する必要がある場合はどうでしょうか。そうすれば、事前にテストを作成するために費やされた多くの作業が無駄な作業になります。

とはいえ、これで問題が解決した場合は問題ありません。固定された詳細な技術仕様を使用していて、親密な経験を積んでいるドメインやかなり小さなタスクで作業している場合、必要なテストケースのほとんどまたはすべてが準備されていて、実装が明確であると想像できます。開始。次に、すべてのテストを一度に記述することから始めるのが理にかなっています。経験上、これにより長期的に生産性が向上する場合、ルールブックについてあまり気にする必要はありません:-)

4
Péter Török

(失敗した)テストを作成した開発者が、テストを成功させるために必要なコードを実装する開発者とは異なるプロジェクトに取り組みましたが、それが本当に効果的であることがわかりました。

その場合、現在の反復に関連するテストのみが一度書き込まれました。したがって、あなたが提案することは、そのようなシナリオでは完全に可能です。

3
user2567
  • 次に、一度に多くのことに集中しようとします。
  • すべてのテストに合格するように実装している間、アプリケーションの作業バージョンはありません。たくさん実装しなければならない場合は、長期にわたって機能するバージョンはありません。
2
magomi

Red-Green-Refactorサイクルは、TDDを初めて使用する開発者を対象としたチェックリストです。いつフォローするか、いつそれを破ることができるかがわかるまで(つまり、stackoverflowでこの質問をする必要がないことがわかるまで)、このチェックリストに従うことをお勧めします。

10年近くTDDを行ってきたので、製品コードを書く前に、失敗するテストを書くことはめったにありません。

2
Torbjörn Kalin

一度に1つのテスト:主な利点は、1つのことに集中することです。深さ優先の設計について考えてください。高速でフィードバックループを使用して、深く掘り下げて集中することができます。ただし、問題全体の範囲を見逃す可能性があります。それが、(大規模な)リファクタリングが登場する瞬間です。それがなければTDDは機能しません。

すべてのテスト:分析と設計により、問題の範囲がさらに明らかになる場合があります。幅優先設計を考えてください。より多くの角度から問題を分析し、経験からの入力を追加します。これは本質的に難しいですが、「十分な量」を実行すると、興味深いリファクタリングが少なくなる可能性があります。過度に分析するのは簡単ですが、それでも完全にマークを逃すことに注意してください!

要因が多いため、一般的にどちらかを優先することを推奨するのは難しいと思います:経験(特に同じ問題について)、ドメインの知識とスキル、リファクタリングのためのコードの親しみやすさ、問題の複雑さ...

典型的なビジネスアプリケーションにさらに焦点を絞れば、TDDの高速でほぼ試行錯誤的なアプローチが、通常、有効性の面で成功するでしょう。

1
MaR

あなたはBDDについて説明していますが、外部の利害関係者は実行可能な仕様を持っています。これは、事前に事前に指定された仕様がある場合(たとえば、フォーマット仕様、工業規格、またはプログラマーがドメインの専門家ではない場合)に役立ちます。

その後、通常のアプローチでは、徐々に受け入れテストをカバーしていきます。これは、プロジェクトマネージャーと顧客に見える進行状況です。

通常、このテストを指定して、Cucumber、FitnesseなどのBDDフレームワークで実行します。

ただし、これは単体テストと混同するものではありません。これは、多くのAPI関連のEdgeケース、初期化の問題など、項目に重点を置いた重要な実装の詳細に非常に近いものですテスト中実装アーティファクトです。

Red-green-refactorの分野には多くの利点があり、それらを前に入力することで期待できる唯一の利点は、均等になることです。

1
Tormod

テストフレームワークがそれをサポートしていると仮定すると、implementingの代わりに、ブレインダンプするテストの代わりに、後で実装する説明的な保留中のテストを記述します。たとえば、APIがfooとbarを実行するがbizは実行しない場合、テストスイートに次のコード(この例はrspecにあります)を追加し、1つずつ攻撃します。あなたはすぐにあなたの考えを落ち着かせ、あなたのすべての問題に一つずつ取り組むことができます。すべてのテストに合格すると、ブレインダンプ中に発生したすべての問題にいつ対処したかがわかります。

describe "Your API" do

  it "should foo" do
    pending "braindump from 4/2"
  end

  it "should bar" do
    pending "braindump from 4/2"
  end

  it "should not biz" do
    pending "braindump from 4/2"
  end

end
1
Ransom Briggs