テスト駆動開発の欠点?[閉まっている]


192

テスト駆動設計を採用すると何が失われますか?

ネガのみをリストします。否定的な形で書かれた利点を挙げないでください。


私は、BDDがこれらのネガティブのいくつかを軽減できると述べた回答を追加しました。否定的なインプットを収集するときは、この要素を検討することをお勧めします。これは、一部の要素を排除でき、もはや否定的とは見なされないためです。
Kilhoffer、2008

25
明確にするために、私は反対も反対もしません。私はこの問題について十分な情報に基づいた決定を下そうとしていますが、TDDを提唱するほとんどの人は理解していないか、ネガティブを認めません。
IanL 2009

1
タイトルは「テスト駆動開発」について言及していますが、質問の本文は「テスト駆動設計」について言及しています。この2つのうちどちらが問題ですか。重要ですが、2つの間に微妙な違いがあります。テスト駆動設計とは、テストにソフトウェアの設計を駆動させることです。テスト駆動開発は、通常、製品コードの前にテストを記述することと関連しています(ただし、必ずしもテストが設計に影響を与えるとは限りません)。
ジム・ハーン2011

3
TDDは、開発者の創造性を拘束するケージです。
ルイス

13
重要な質問を閉じるのをやめてください、ジェスス
キャスパーレオンニールセン

回答:


129

いくつかの不利な点があります(そして、特にプロジェクトの基礎を書くときに、利点がないと主張していません-それは最後に多くの時間を節約します):

  • 大きな時間の投資。単純なケースでは実際の実装の約20%が失われますが、複雑なケースでははるかに多くが失われます。
  • 追加の複雑さ。複雑なケースの場合、テストケースの計算が難しくなります。そのような場合は、最も単純なケースの単体テストの代わりに、デバッグバージョン/テストの実行で並行して実行される自動参照コードを使用してみることをお勧めします。
  • 設計への影響。時々、デザインは最初は明確ではなく、進むにつれて進化します-これはあなたにテストをやり直すことを強いるでしょう、それは大きな時間のロスを生成します。この場合、設計をある程度把握できるまで、単体テストを延期することをお勧めします。
  • 継続的な微調整。データ構造とブラックボックスアルゴリズムの単体テストは完璧ですが、変更、微調整、微調整される傾向のあるアルゴリズムの場合、これは正当な理由がないと主張する可能性のある多大な時間の投資を引き起こす可能性があります。したがって、実際にシステムに適合すると考え、設計をTDDに適合させない場合に使用します。

7
主なポイント(4)は-明確に定義されておらず、進化する視覚的動作、さまざまなAI仕様、動作アルゴリズムなどに合わせて変化し続ける可能性があるシステムは、繰り返しテスト定義に多大な時間を費やすことになるため、望ましいテスト結果の変更について。
Adi

12
本当ですが、TDDがないと同じではないでしょうか。それがなければ、同じ問題に苦しむより多くの手動テストを行う必要があります。
sleske 2010

50
「ビッグタイムへの投資」によって、ソリューションの開発中に時間を節約できませんか?特に複雑なものでは?時間を節約できると思います。小さな変更でシステムが壊れやすいメンテナンスフェーズについては考えないでください。(または、ユニット+回帰テストが将来のバグを防ぐことについて単にナイーブなだけかもしれません
Robert Koritnik

6
セルジオ/ロバート、私は一般的なシステムのユニットテスト、そして間違いなくシステムの基本を表すコンポーネントをテストすることに非常に賛成です。そうは言っても、すべてのシステムをこのように扱うことができると主張することで、これらのケースを区別し、実際の生活を単純化しすぎる必要があることを付け加えておきます。すべてのシステムを単体テスト用に一般化および簡略化できるわけではありません。そのようなシステムで単体テストの性質を強制しようとすると、実際の結果を実際にテストするよりもはるかに多くの時間を単体テストの修正に費やすことになります。
2014

3
@アディ:私はあなたが間違っていると思います。私の意見では、すべてのシステムをそのようにテストすることができます。それは自己規律の問題だけです。
BlueLettuce16、2015年

189

「実際の」TDD(読み取り:最初に赤、緑、リファクターステップでテストする)を実行する場合は、統合ポイントをテストするときにモック/スタブの使用を開始する必要もあります。

モックの使用を開始するとき、しばらくすると、依存性注入(DI)と制御の反転(IoC)コンテナーの使用を開始する必要があります。そのためには、すべてにインターフェースを使用する必要があります(それ自体に多くの落とし穴があります)。

結局のところ、単に「古い方法」で行う場合よりも、はるかに多くのコードを記述する必要があります。単なる顧客クラスの代わりに、インターフェース、モッククラス、いくつかのIoC構成、およびいくつかのテストを作成する必要もあります。

また、テストコードも維持および管理する必要があります。テストは他のすべてと同じように読みやすくする必要があり、優れたコードを書くには時間がかかります。

多くの開発者は、これらすべてを「正しい方法」で行う方法を完全に理解していません。しかし、TDDがソフトウェアを開発するための唯一の真の方法であると誰もが言うので、彼らはできる限り最善を尽くします。

想像以上に難しいです。多くの場合、TDDを使用して行われたプロジェクトは、誰も本当に理解していない大量のコードを生成します。単体テストは、多くの場合、間違ったもの、間違った方法をテストします。そして、いわゆるテストの達人でさえも、良いテストがどのように見えるべきかについて誰も同意しません。

これらすべてのテストにより、システムの動作を「変更」する(リファクタリングとは逆に)のが非常に難しくなり、単純な変更が非常に難しくなり、時間がかかります。

TDDの資料を読むと、常に非常に優れた例がいくつかありますが、実際のアプリケーションでは、多くの場合、ユーザーインターフェイスとデータベースが必要です。これはTDDが本当に難しくなる場所であり、ほとんどのソースは良い答えを提供していません。そして、もしそうなら、それは常により多くの抽象化を含みます:モックオブジェクト、インターフェースへのプログラミング、MVC / MVPパターンなど、これもまた多くの知識を必要とします...そしてさらに多くのコードを書かなければなりません。

ですので、注意してください...熱心なチームがなく、優れたテストを書く方法を知っていて、優れたアーキテクチャに関するいくつかのことを知っている経験豊富な開発者が1人もいない場合、TDDの道を進む前によく考えなければなりません。 。


7
Pex&Molesのようなツールを使用すると、すべての小さな物のためのインターフェースを書くことを簡単に回避できます。ほくろは途方もなくそれであなたを助けます。
Robert Koritnik

24
TDDではなく、単体テストとオブジェクト指向プログラミングの批評のようです。
plmaheu 2013

5
実際に正しい**単体テスト** – TDDだけでなく–モック/スタブが必要です。また、インターフェースに対するプログラミングは、多くの場合良い考えです。同じことがパターンにも当てはまります。UIとロジックを混在させると、時間がかかります。DBの相互作用をテストする必要がある場合でも、単体テスト用にDAOをモックして、統合テストに本物を使用できます。
TheMorph 2014年

1
1人のミストがtddに飛び込む前に設計とテストの知識を持っているという事実に同意します。どちらも新しいので、これは新規採用のプロジェクトでは重要です。
Hitesh Sahu

知恵に投票する
sabsab 2017

66

多数のテストがあるポイントに達した場合、システムを変更すると、変更によって無効にされたテストに応じて、テストの一部またはすべてを書き直すことが必要になる場合があります。これは、比較的迅速な変更を非常に時間のかかるものに変える可能性があります。

また、実際に優れた設計担当者よりもTDDに基づいて設計決定を始める場合もあります。TDDが要求する方法をテストすることは不可能である非常にシンプルで簡単なソリューションがあったかもしれませんが、実際には間違いを起こしやすいはるかに複雑なシステムがあります。


3
間違いなく問題になる可能性がありますが、これによる影響の度合いに顕著な違いが見られます。すべては「テスト可能なコードを書く」ことになると思います。
Rob Cooper、

2
スコット、私が通常挙げる例は、ASPXページに埋め込まれたSqlDataSourceです。そのためのテストを自動化することはできません。それはシンプルで、たった1つのファイルでジョブを完了します。テスト可能なコンポーネントはMSFTのSqlDataSourceオブジェクトで、これは既に行われています。これ以上行う必要はありません。
エリックZビアード

8
+1「実際に優れた設計主体よりもTDDに基づいて設計決定を始める可能性がある」-TDD IMHOの最大の落とし穴。
アンドラーシュSzepesházi

2
@ScottSaad問題IMOは、設計を最初に概説し、次にテストを記述して検証し、必要に応じて修正する必要があることです。テストを書けるようにするためだけに、人々が良いデザインを危険にさらしていた多くのケースを見てきました。結果として、システムのほとんどはテストでカバーされましたが、設計は本当に醜いものでした。私は、TDDは、以下と非常にシンプルな方法論として大衆にプッシュされるので、これが起こると思い誤解if part of the system is covered by tests and they pass, then everything is fine (including design)
Yuriy Nakonechnyy 2014

3
@由良:テストを書けるようにするためだけに人々が良いデザインを危険にさらしていたのは興味深いことです。私の意見では、良いデザインがあればそれを危険にさらす必要はないでしょう。私はかつてそのようなプロジェクトを見たことがあり、コードベースは悪夢でしたが、人々は同じことを考えました-デザインは素晴らしいです。TDDが非常に単純な方法論として大衆にプッシュされているという部分にのみ同意しますが、それは正反対です。私の意見では、コードが適切に設計されていて、1つの小さな変更を行った場合、すべてのテストまたは大量のテストにブレーキをかけることはできません。
BlueLettuce16、2015年

54

私にとって最大の問題は、「それに取り掛かる」のに要する時間が大幅に失われることです。私はまだTDDの旅の始まりに非常に近く(興味があれば、私のテストアドベンチャーの更新については私のブログを参照してください)、文字通り何時間もかけて始めました。

脳を「テストモード」にするのに長い時間がかかり、「テスト可能なコード」を書くこと自体がスキルです。

TBH、私はプライベートメソッドを公開することについてのJason Cohenのコメントに敬意を払いません。それはそれについてではありません。私はこれまでよりも新しい働き方でパブリックメソッドを作成していません。ただし、アーキテクチャの変更が必要であり、コードの「ホットプラグ」モジュールを使用して、他のすべてのものをテストしやすくすることができます。これを行うには、コードの内部にアクセスしやすくするべきではありません。それ以外の場合は、すべてがパブリックであるスクエア1に戻ります。そのカプセル化はどこにありますか?

つまり、(IMO)一言で言えば:

  • 考えるのにかかった時間(つまり、実際にテストを行う)。
  • テスト可能なコードの記述方法を知るために必要な新しい知識。
  • コードをテスト可能にするために必要なアーキテクチャの変更について理解する。
  • 輝かしいプログラミング技術に必要な他のすべてのスキルを向上させながら、「TDD-Coder」のスキルを向上させます:)
  • プロダクションコードをねじ込むことなくテストコードを含めるようにコードベースを編成する

PS:ポジティブへのリンクが必要な場合は、いくつかの質問をして回答しました。私のプロフィールを確認してください。


1
悲しいことに、私が見た最初の合理的な答えは...
ダニエルC.ソブラル

5
かなり実用的で単純な答え-「マインド設定」の部分に+1
ha9u63ar

50

私がテスト駆動開発を実践してきた数年の間に、最大の欠点は次のとおりです。

経営者に売る

TDDはペアで行うのが最適です。あなたはとき一つには、それだけで実装を作成する衝動に抵抗するのは難しい知って書き込む方法の場合/他の文を。しかし、あなたが彼を任務に留めているので、ペアはあなたを任務に留めます。残念なことに、多くの企業/マネージャーは、これがリソースの有効利用であるとは考えていません。同時に2つの機能を実行する必要があるのに、1つの機能を作成するのに2人で支払うのはなぜですか?

他の開発者に販売する

一部の人々はユニットテストを書くための忍耐力がありません。彼らの仕事をとても誇りに思う人もいます。または、複雑なメソッド/関数が画面の端から流れ出るのを見るようなものもあります。TDDはすべての人に適しているわけではありませんが、本当にそうであるといいのですが。コードを継承する貧しい人々にとって、それはものを維持することをとても簡単にします。

テストコードとプロダクションコードの維持

理想的には、テストは、コードを間違って決定した場合にのみ中断します。つまり、システムは一方向に機能すると思っていましたが、機能しないことがわかりました。テストまたは(小さな)テストのセットを壊すことによって、これは実際に良いニュースです。新しいコードがシステムどのように影響するかを正確に知っています。ただし、テストの記述が不十分、密結合、またはさらに悪い場合は生成された場合( VSテスト)、テストの維持がすぐに合唱になる可能性があります。そして、十分なテストが開始して、それらが作成していると認識された値よりも多くの作業を引き起こすようになった後、スケジュールが圧縮されたときに、テストが最初に削除されます(たとえば、処理時間に達した場合)。

すべてを網羅するようにテストを作成する(100%コードカバレッジ)

理想的には、ここでも、方法論を順守する場合、コードはデフォルトで100%テストされます。通常、私はコードカバレッジが90%以上になると思っていました。これは通常、いくつかのテンプレートスタイルのアーキテクチャがあり、ベースがテストされているときに、テンプレートのカスタマイズをテストせずに隅を切り取ろうとしたときに発生します。また、私が以前に経験したことのない新しい障壁に遭遇したとき、それをテストする際に学習曲線があることがわかりました。私はいくつかのコード行を古いskoolの方法で書くことを認めますが、私はそれを100%にするのが本当に好きです。(私は学校で過大な達成者だったと思います、er skool)。

ただし、TDDの利点は、アプリケーションをカバーする一連の優れたテストを達成できても、1つの変更ですべてが壊れるほど脆弱ではないという単純な考えの欠点をはるかに上回っていると私は言います。プロジェクトの1日目と同じように、プロジェクトの300日目に新しい機能を追加し続けることができます。これは、TDDを試すすべての人が、バグに覆われたすべてのコードの魔法の弾丸であると考えているわけではありません。機能しない、期間。

個人的には、TDDを使用すると、より単純なコードを記述し、特定のコードソリューションが機能するかどうかの議論に費やす時間が減り、以下に示す基準を満たさないコード行を変更する恐れがないことがわかりましたチーム。

TDDは習得するのが難しい分野です。私は数年このTDDに取り組んでいますが、それでも新しいテスト手法を常に学んでいます。事前に莫大な時間を投資することですが、長期的には、自動化された単体テストがない場合よりも持続可能性がはるかに高くなります。さて、私のボスだけがこれを理解できたら。


7
「(咳VSテスト)、その後メイン」で終わる文の残りは何でしたか?
Andrew Grimm、

販売問題の+1。:)私は今、新しい会社にいて、スキルを自由に広めることができる文化をどのように作成するかを考えています。
Esko Luontola

2
あなたが考えるように、一部のコンサルタント会社は、クライアントからより多くのお金を稼ぐためにペアプログラミングとTDDを利用しています。2人が2人よりはるかに優れている、またはTDDがコードのすべての行がテストされることを保証するなど、一見合理的であると思われるアイデアに対してこれらのクライアントが支払う方法にかなりがっかりしますが、結局のところ、彼らはクライアントに支払うことの言い訳にすぎません一人だけができることのためにもっと。
lmiguelvargasf

24

最初のTDDプロジェクトでは、時間と個人の自由という2つの大きな損失があります。

あなたは時間を失う:

  • 包括的でリファクタリングされた、保守可能な単体テストと受け入れテストのスイートを作成すると、プロジェクトの最初の反復にかなりの時間がかかります。これは、長い目で見れば時間の節約になりますが、同様に、時間を節約する必要がない場合もあります。
  • コアツールセットを選択してエキスパートになる必要があります。単体テストツールは、ある種のモックフレームワークで補完する必要があり、両方とも自動ビルドシステムの一部になる必要があります。また、適切なメトリックを選択して生成する必要もあります。

次の理由で個人の自由を失う:

  • TDDは、スキルスケールの上位および下位のコードに対して生でこする傾向があるコードを書くための非常に統制のとれた方法です。常に特定の方法でプロダクションコードを記述し、継続的にピアレビューを行うことは、最悪で最高の開発者を驚かせ、人員を失うことさえあります。
  • TDDを組み込むほとんどのアジャイルメソッドでは、達成することを提案すること(このストーリー/日/何でも)とトレードオフについて、クライアントと継続的に話す必要があります。もう一度言いますが、これは、フェンスの開発者側とクライアントの両方にとって、すべての人のお茶ではありません。

お役に立てれば


1
それが私が最悪なのか最高なのかはわかりませんが、TDDは間違った方法でこすります。それは私が早めにデュアルメンテナンスモードに強制するためです。クラスのデザインを変更するたびに、テストケースも変更する必要があります。私は成熟したクラスからそれを期待して受け入れますが、先週書いたばかりのクラスからではありません!また、DIやTDDはJavaやC#などの言語では十分にサポートされていないと言えます。TDDとDIのコストが文字通りゼロになるように、誰かが本当に新しい言語を作成する必要があります。その後、この会話はもうありません。
John Henckel

14

TDDでは、これらのテストに合格するコードを記述する前に、クラスがどのように動作するかを計画する必要があります。これはプラスにもマイナスにもなります。

「真空」でコードを書く前にテストを書くのは難しいと思います。私の経験では、最初のテストの作成中に忘れていたクラスを作成しているときに必然的に何かを考えるときはいつでも、自分のテストをトリップする傾向があります。次に、クラスをリファクタリングするだけでなく、テストも行います。これを3〜4回繰り返すと、イライラすることがあります。

最初にクラスのドラフトを作成してから、一連の単体テストを作成(および保守)することを好みます。下書きを作成した後、TDDは問題なく機能します。たとえば、バグが報告された場合、そのバグを悪用するためのテストを記述し、テストに合格するようにコードを修正します。


1
システムのアーキテクチャがどのようになるかを理解している必要がありますが、TDDを実行するときに、事前に多くのことを知る必要はありません。TDDは、テストが設計を
推進

4
私は掃除機に同意します。コードを一切使わずにテストを記述し、コンパイルエラーが発生するTDDの元のチュートリアルは、クレイジーです。
mparaz 2009年

テストを1度だけ記述でき、それらを変更しないというのは間違った前提です。これらはコードであり、変更を行った後、すべてのコードで最終的なリファクタリングが必要です。テストも例外ではありません。テストを保守しやすくするには、テストのリファクタリングが不可欠です。
Roman Konoval

12

TDDではプロトタイピングが非常に困難になる可能性があります。ソリューションへの道がわからない場合、(非常に広範なテストを除いて)テストを事前に作成することが困難な場合があります。これは苦痛になることがあります。

正直なところ、大多数のプロジェクトの「コア開発」には、実際にはマイナス面があるとは思いません。通常、コードがテストを必要としないほど十分であると信じている人(それは決して必要ではありません)や、単純にコードを書くのに煩わされない人によって、それは必要以上に多くのことを語られています。


9

さて、このストレッチでは、テストをデバッグする必要があります。また、テストの作成にはある程度のコストがかかりますが、ほとんどの人は、デバッグ時間の節約と安定性の両方の点で、アプリケーションの存続期間を通じて成果を上げる先行投資であることに同意します。

しかし、私が個人的に抱えていた最大の問題は、実際にテストを作成するための規律を立てることです。チーム、特に確立されたチームでは、費やした時間に価値があると彼らを納得させるのは難しい場合があります。


13
Aha-しかし、そこがTDTDDの出番です。テスト駆動型テスト駆動開発。
Snowcrash

3
テストテストでまだ時々バグが見つかります。だから今私はTDTDTDDを練習します。
HorseloverFat

@SnowCrash +1私はGoogleの周りを見て、人々がテストのテストに費やす時間について調べていたところ、この答えを見ました。TDTDTDDについて疑問に思っていたので、これを正式に見つけました。
BalinKingOfMoriaのCMを2015

1
未来は(TD)<sup>∞</ sup> TDDだと思います。これまでに1つのファイルがあります。「x」という文字が含まれています。
マイクげっ歯類

@Timに同意します。それを採用するようにメンバーを説得することは最も難しい部分です。
Olu Smith

7

テストがあまり徹底的でない場合、テストに合格したというだけで、「すべてが機能する」という誤った感覚に陥る可能性があります。理論的には、テストに合格した場合、コードは機能しています。しかし、初めてコードを完全に書くことができれば、テストは必要ありません。ここでの教訓は、テストに依存するのではなく、何かを完了する前に、自分でサニティチェックを必ず行うことです。

その点について、サニティチェックでテストされていないものが見つかった場合は、戻ってそのテストを作成してください。


私は大人になったので正気の条項がないとは信じていません。
マイクげっ歯類

7

TDDの欠点は、通常、「アジャイル」の方法論と密接に関連しているため、システムの文書化は重要ではなく、テストが特定の値を返す必要がある理由が、開発者にのみ存在するのではなく、その背後にあるという理解です。頭。

テストが特定の値ではなく他の特定の値を返す理由を開発者が去るまたは忘れるとすぐに、あなたはうんざりしています。TDDは、適切に文書化され、人間が読める(つまり、先のとがった髪のマネージャー)文書で囲まれていれば問題ありません。5年間で世界が変わり、アプリも同様に参照できるようになります。

ドキュメンテーションについて話すとき、これはコードの言い訳ではありません。これは、アプリケーションの外部に存在する公式な記述です。たとえば、マネージャー、弁護士、および更新しなければならない貧しいsapが参照できるユースケースや背景情報などです。 2011年のコード。


1
完全に置く。私はこれ以上同意できませんでした。私にとって、テストは確かに実際のより高いレベルの問題定義を説明するのに役立ちません。優れたドキュメントは、その価値を何度も繰り返し証明しています。技術として。業界の年齢、定評のある概念は、これまで以上に注意深く使用する必要はありません。自己文書化コードはばかげた概念です。私は、プロトタイピング、リファクタリング、そして最初から問題を定義することのない俊敏性を信じています。ただし、皮肉なことに、最初から問題を過度に定義しないと、TDDのスタブが地雷原になります。
–wax_lyrical

1
これは不当だと思います。優れたTDDプラクティスは、マジックナンバーとあいまいなテストを非難します。テストは単純で、本番用コード自体と同じか、できればもっと読みやすくする必要があります。テストはドキュメントです。彼らがそれのように見えることを確認してください。この答えは、「ドキュメントは悪いドキュメントを書くことがあるので、ドキュメントは悪い」または「扱いにくい神のクラスをいくつか見たことがあるので、クラスは悪い」と言うような感じがします。
サラ2016

6

TDDに夢中になるいくつかの状況に遭遇しました。名前を付けるには:

  • テストケースの保守性:

    大企業の場合、多くの場合、自分でテストケースを作成する必要がないか、少なくともほとんどの場合、会社に入社したときに他の人がテストケースを作成します。アプリケーションの機能は随時変更され、HP Quality Centerなどのシステムを配置してそれらを追跡する機能がないと、すぐに夢中になります。

    これはまた、テストケースで何が行われているのかを把握するには、新しいチームメンバーにかなりの時間がかかることを意味します。次に、これはより多くの必要なお金に変換できます。

  • テスト自動化の複雑さ:

    テストケースの一部またはすべてを自動化してマシンで実行可能なテストスクリプトにする場合は、これらのテストスクリプトが対応する手動テストケースと同期し、アプリケーションの変更に沿っていることを確認する必要があります。

    また、バグの発見に役立つコードのデバッグにも時間を費やします。私の意見では、これらのバグのほとんどは、テストチームがアプリケーションの変更を自動化テストスクリプトに反映できなかったことが原因です。ビジネスロジック、GUI、およびその他の内部的な要素の変更により、スクリプトの実行が停止したり、実行が不安定になったりする可能性があります。変更は非常に微妙で、検出が難しい場合があります。テーブル1がテーブル2になったときに、テーブル1からの情報に基づいて計算を行ったため、すべてのスクリプトが失敗を報告します(誰かがアプリケーションコードでテーブルオブジェクトの名前を入れ替えたため)。


これはTDDをまったく扱いません。別の部門の他の誰かがテストケースを書いている場合、TDDを行っていません。手動テストケースがある場合は、TDDを実行していません。ライブラリコードが壊れ、GUIの変更が原因でテストが失敗した場合は、おそらくTDDも行っていません。これは、大規模な非効率的なエンタープライズQA部門に対する反対論のように見えます。
サラ2016

5

最大の問題は、適切な単体テストの書き方を知らない人々です。それらは互いに依存するテストを記述します(そして、Antで実行するとうまく機能しますが、Eclipseから実行すると、それらが異なる順序で実行されるという理由だけですべてが突然失敗します)。彼らは特に何もテストしないテストを書きます-彼らは単にコードをデバッグし、結果をチェックし、それをテストに変更して、それを「test1」と呼びます。それらがユニットテストを書くのが簡単になるからといって、それらはクラスとメソッドのスコープを広げます。単体テストのコードはひどいもので、すべての古典的なプログラミングの問題(重い結合、500行の長さのメソッド、ハードコードされた値、コードの重複)があり、維持するのは大変です。奇妙な理由で、人々はユニットテストを「実際の」コードよりも劣ったものとして扱います。tすべての品質を気にします。:-(


4

テストの作成に費やされた多くの時間を失います。もちろん、これはプロジェクトの終わりまでにバグをより早く見つけることで保存されるかもしれません。


これは本当にネガティブなことですか、それともポジティブな言い方のずるい方法ですか。
IanL 2008

3

最大の欠点は、本当にTDDを適切に実行したい場合、成功する前に多くの失敗をしなければならないことです。いくつのソフトウェア会社が働いているか(KLOCあたりのドル)を考えると、やがて解雇されます。コードがより速く、よりクリーンで、メンテナンスがより簡単で、バグが少ない場合でも。

KLOC(または、テストされていなくても実装されている要件)で支払いを行う会社で働いている場合は、TDD(またはコードレビュー、ペアプログラミング、継続的統合など)を避けてください。


3

すべてのコードをテストする前に、「完了」したとは言えなくなります。

実行する前に、数百または数千行のコードを書き込む機能を失います。

デバッグを通して学ぶ機会を失います。

確信が持てないコードを出荷する柔軟性が失われます。

モジュールを密結合する自由が失われます。

低レベルの設計ドキュメントの作成をスキップするオプションを失います。

誰もが変更を恐れているコードに付随する安定性が失われます。


1
「時間どおりにソリューションを提供する」というあなたの定義に依存します。それは、「古い、部分的に壊れたソリューションを時間どおりに提供する」、または「作業ソリューションを時間どおりに提供する」ということです。あなたは確かに時間通りに部分的に壊れたソリューションを提供する能力を失います。開発速度に関する限り、私は「開発の開始から障害のないライブデプロイメントの1週間までの経過時間」というメトリックが好きです。公平に測定すると、TDD以外の作業のcopmlex部分で時計を停止することすら困難です。
Dafydd Rees、

47
-1、これはまさにOPが彼が望んでいないと言ったことです。
erikkallen 2009

1
多くの真実の声明、しかし:エリックカレンが言ったこと。-1。
j_random_hacker

@ j_random_hackerはハッカーと言っています... LOL
Dan

3番目のステートメントのみが合法である「デバッグによる学習は失われる」
YEH

2

最初の開発時間についての回答を2番目に述べます。また、テストの安全性がなくても快適に作業する能力を失います。私はTDDナットバーとも呼ばれているので、数人の友達を失う可能性があります;)


2

遅いと考えられています。長期的には悲しみの点では正しくありませんが、将来的には節約できますが、最終的にはより多くのコードを書くことになり、間違いなく「コーディングではなくテスト」に時間を費やすことになります。それは欠陥のある議論ですが、あなたは尋ねました!


2

プログラマーの悩みの種である、困難で予期せぬ要件に再び焦点を当てること。テスト駆動型の開発では、既知のありふれた要件に集中する必要があり、開発はすでに想像されているものに限定されます。

考えてみれば、最終的には特定のテストケースに合わせて設計することになるので、独創的でなく、「ユーザーがX、Y、Zを実行できればいいのではないか」と考え始めることはありません。したがって、そのユーザーが潜在的なクールな要件X、Y、およびZについてすべて興奮し始めると、設計はすでに指定されたテストケースに厳格に集中しすぎて、調整が困難になる可能性があります。

もちろんこれは両刃の剣です。ユーザーが望む可能性のあるすべての考えられる、想像できる、X、Y、およびZの設計にすべての時間を費やした場合、必然的に何も完了することはありません。何かを完了すると、誰でも(自分を含む)がコード/デザインで何をしているのかを知ることができなくなります。


考えてみれば、最終的には特定のテストケースに合わせて設計することになるので、独創的でなく、「ユーザーがX、Y、Zを実行できればいいのではないか」と考え始めることはありません。-私の意見では、それは正反対です。ユニットテストを作成する場合、さまざまなビジネスケースについて疑問に思うでしょう。これは、創造的であり、予期しない何かを予見することを可能にすることを意味します。ただし、実装にバグがある場合、そのすべての創造性は重要ではありません。
BlueLettuce16、2015年

1

XMLフィードやデータベースなどの「ランダム」データのテストを作成するのは、難しくて時間がかかる場合があります(それほど難しくありません)。最近、天気データフィードの操作に少し時間を費やしました。少なくともTDDの経験があまりないので、そのためのテストを書くのはかなり混乱します。


これはよくある問題です。私はこれらをハードコードされたオブジェクトでモックし、データベースを個別にテストする傾向があります。ビジネスレイヤーは静的データでのみ機能し、DALは制御された環境でテストされます(そこでデータをスクリプト化できるなど)
Rob Cooper

1

あなたは複数の責任を持つ大きなクラスを失うでしょう。また、複数の責任を持つ大きなメソッドを失う可能性があります。リファクタリングの能力がいくらか失われる可能性がありますが、リファクタリングの必要性の一部も失われます。

Jason Cohen氏は次のように述べています。TDDには、コードに特定の組織が必要です。これはアーキテクチャ的に間違っている可能性があります。たとえば、プライベートメソッドはクラスの外部で呼び出すことができないため、メソッドをテスト可能にするには、メソッドを非プライベートにする必要があります。

私はこれが抽象化の失敗を示していると言います-プライベートコードが本当にテストされる必要があるなら、それはおそらく別のクラスにあるべきです。

デイブ・マン


1

アプリケーションは別の方法で作成する必要があります。それは、アプリケーションをテスト可能にする方法です。これが最初はどれほど難しいか、きっと驚くでしょう。

一部の人々は、書く前に何を書くかについて考えるという概念が難しすぎることに気づきます。モックなどの概念は、一部の人にとっても難しい場合があります。レガシーアプリのTDDは、テスト用に設計されていない場合、非常に難しい場合があります。TDDに対応していないフレームワークの周りのTDDも、苦労する可能性があります。

TDDは、ジュニア開発者が最初に苦労する可能性があるスキルです(主に彼らがこのように動作するように教えられていなかったため)。

全体的には、人々が熟練し、「臭い」コードを抽象化して、より安定したシステムを持つようになると、短所は解決されます。


1

プロジェクトに取り掛かるまでにはしばらく時間がかかりますが、プロジェクトでそれを始めるにはしばらく時間がかかりますが...自動テストで非常に高速に検出される可能性のある愚かなバグを見つけたとき、私は常にテスト駆動アプローチを実行しないことを後悔しています。さらに、TDDはコード品質を向上させます。


1
  • 単体テストはより多くのコードを記述する必要があるため、開発の先行投資コストが高くなります
  • 維持するコードが多い
  • 追加の学習が必要

1

すべて良い答えです。TDDのダークサイドを回避する方法をいくつか追加します。

  • 独自のランダム化されたセルフテストを実行するアプリを作成しました。特定のテストを作成する際の問題は、多くのテストを作成しても、考えられるケースのみをカバーすることです。ランダムテストジェネレーターは、あなたが考えていなかった問題を見つけます。

  • 多数の単体テストの概念全体は、複雑なデータ構造など、無効な状態になる可能性のあるコンポーネントがあることを意味します。複雑なデータ構造に近づかないと、テストする必要がはるかに少なくなります。

  • アプリケーションが許可する範囲で、通知、イベント、および副作用の適切な順序に依存する設計には気を付けてください。それらは簡単に落ちたりスクランブルされたりする可能性があるため、多くのテストが必要です。


ランダムテストは断続的に失敗し、繰り返しを困難にする可能性があります
David Sykes

@DavidSykes:ランダムテストを実行するときはいつでも、パラメーターを記録して、失敗した場合にそれを繰り返したり、失敗しなかった場合でも後で繰り返したりできるようにします。ポイントは、テストケースを考えることはあなたに依存しないということです。あなたが私のような人なら、あなたは本能的に安全なテストケースに引き寄せられます。
Mike Dunlavey、2014年

0

TDDでは、コードに特定の組織が必要です。これは非効率的または読みにくい場合があります。または、アーキテクチャ的にも間違っています。たとえば、privateメソッドはクラスの外では呼び出せないため、メソッドを非公開にしてテスト可能にする必要がありますが、これは間違っています。

コードが変更されると、テストも変更する必要があります。リファクタリングでは、これは多くの追加作業になる可能性があります。


9
すべてのプライベートメソッドは、とにかく存在するパブリックメソッドを通じてテストする必要があります。
Garry Shutler、

これはすべてのクラスで可能ではありません。すべての依存関係などをモックアップしたくない場合や、ユーティリティメソッドをテストしたい場合があります。
Jason Cohen

+1、真実。状態をクラスに対してプライベートにする必要がある場合でも、ユニットテストの状態を正しく設定して読み取ることができるようにするために、ゲッター/セッターをプライベートフィールドに追加する場合があるという要件をこれに追加します。
erikkallen 2009

それが実際の要件ドキュメントであるかのようにテストを書くことを検討してください。それからあなたは光を見ます。XUnitテストパターンもご覧ください。
スコットニムロッド

0

BDDの原則をTDDプロジェクトに適用すると、ここにリストされているいくつかの主要な欠点(混乱、誤解など)を軽減できることを付け加えておきます。BDDに慣れていない場合は、Dan Northの紹介を読んでください。彼は職場でTDDを適用することから生じたいくつかの問題に答えてコンセプトを思いつきました。ダンのBDDの紹介はここにあります

BDDはこれらの欠点のいくつかに対処し、ギャップストップとして機能するため、この提案をします。フィードバックを収集する際は、この点を考慮してください。


もちろんです。TDDを評価するときは、BDDを考慮する必要があります。
user9991 2008

BDD =振る舞い主導の開発のようです
hayalci

0

テストが常に最新であることを確認する必要があります。赤信号を無視し始めた瞬間が、テストが無意味になった瞬間です。

また、テストが包括的であることを確認する必要があります。そうしないと、大きなバグが発生した瞬間に、最終的にコードの記述に時間を費やすことができると確信したムッとした管理タイプが文句を言います。


0

私のチームにアジャイル開発を教えた人は、計画を信じていませんでした。あなたは、ごくわずかな要件のために多くを書きました。

彼のモットーはリファクタリング、リファクタリング、リファクタリングでした。リファクタリングは「事前に計画しない」ことを意味することを理解するようになりました。


-1

開発時間の増加:すべてのメソッドにはテストが必要であり、依存関係のある大規模なアプリケーションがある場合は、テスト用にデータを準備してクリーンアップする必要があります。


:私は今、この記事はあなたにいくつか良いアドバイスを与えることが36の賛否のために開発されてきたstackoverflow.com/questions/738539/tdd-how/45971814#45971814
user2288580
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.