テスト駆動開発(TDD)は実際に実際のプロジェクトに利益をもたらしましたか?


36

コーディングは初めてではありません。私は今15年以上にわたって(まじめに)コーディングしてきました。私はいつも自分のコードに対していくつかのテストを行ってきました。ただし、ここ数か月にわたって、Ruby on Railsを使用してテスト駆動設計/開発(TDD)を学んでいます。これまでのところ、私は利益を見ていません。

いくつかのテストを書くことにはいくつかの利点がありますが、ごくわずかです。そして、最初にテストを書くというアイデアは好きですが、実際のコードをデバッグするよりも、テストのデバッグに時間を費やして、自分の本当の意味を伝えるようにします。これはおそらく、テストコードがテストするコードよりもかなり複雑になることが多いためです。これが利用可能なツール(この場合はRSpec)に不慣れであることを願っています。

ただし、この時点で、失望のレベルと期待を裏切るパフォーマンスの欠如が許容できないレベルを超えています。これまでのところ、TDDから私が見ている唯一の価値は、他のプロジェクト/ファイルのテンプレートとして機能するRSpecファイルの成長するライブラリです。これは実際のプロジェクトコードファイルよりもはるかに有用ではなく、おそらくあまり有用ではありません。

入手可能な文献を読むと、TDDは前もって大きな時間を費やしているように見えますが、最終的には報われます。私はただ疑問に思っています、実世界の例はありますか?この大きな不満は現実の世界で報われるのでしょうか?

ここのどこかでこの質問を見逃さなかったことを本当に願っています。検索しましたが、この時点ですべての質問/回答は数年前のものです。TDDについて悪いことを言う開発者を見つけたのはめったにありませんでした。しかし、特定の実世界の例を指し示している人はいないようです。2011年にコードをデバッグしている人は、完全な単体テストスイートを用意してくれてありがとう(コメントは2008年に作成されたと思います)という答えを1つ読みました。

だから、私は、これらすべての年月の後に、ペイオフが本物であることを示す例が最終的にありますか?TDDを使用して設計/開発され、単体テストの完全なセットを持ち、実際に見返りを感じたコードを実際に継承または戻した人はいますか?それとも、テストが何をテストしているのか(そしてなぜそれが重要だったのか)を把握しようとして非常に多くの時間を費やしていたので、コードを掘り下げて掘り下げましたか?


1
同じプロジェクトに多くの人がいるため、gemの更新には未知の副作用がある可能性があるためです
無呼吸


3
butunclebob.com/ArticleS.UncleBob.JustTenMinutesWithoutAtestこれは、ボブおじさんが実際に直面した状況についての話です。
ハカンデリアル

1
最初は、バグがどこにないかを知るのにテストは素晴らしいと思いましたが、@ Hakanがボブおじさんの記事で指摘したように、一般的にはテストケースを見逃したために起こります。そのため、これらのテストはほとんど役に立ちません。実際、その記事では、インクリメンタル開発が機能するという点を強調しています。
ジェームズ

1
「私は、私は実際のコードをデバッグするかよりも、私は彼らが私が本当に言いたいことを言うために得るために、私のテストをデバッグしようとして実質的に多くの時間を過ごす見つける」:これは、正確な利益ではないでしょうか?その後、「実際のコード」のデバッグに多くの時間を費やしていることに気づきましたか?TDDの支持者は、コードをテスト可能にする方法を見つけるのに費やした時間は、実際にはコードに利益をもたらす設計努力だと主張しています。
アンドレスF.

回答:


26

このホワイトペーパーでは、TDDにより、開発期間が15〜35%増加し、それ以外の場合は類似プロジェクトの欠陥密度が40〜90%減少することを示しています。

記事は完全な紙参照(PDF) - Nachiappan Nagappan、E.マイケルマクシミリアン、Thirumalesh Bhatさん、そしてローリー・ウィリアムズ。「テスト駆動開発による品質改善の実現:4つの産業チームの結果と経験」。ESE 2008

抽象テスト駆動開発(TDD)は、数十年にわたって散発的に使用されてきたソフトウェア開発手法であり、この手法により、ソフトウェアエンジニアは、失敗した単体テストの記述と、それらのテストに合格するための実装コードの記述を1分ごとに繰り返します。テスト駆動開発は、アジャイルソフトウェア開発方法論の重要な実現プラクティスとして最近再登場しました。しかし、ほとんどの経験的証拠は、産業的文脈におけるこの慣行の有用性を支持または反論していません。ケーススタディは、TDDを採用したマイクロソフトの3つの開発チームとIBMの1つの開発チームで実施されました。ケーススタディの結果は、TDDプラクティスを使用しなかった同様のプロジェクトと比較して、4つの製品のリリース前の欠陥密度が40〜90%減少したことを示しています。主観的に、

論文では、George and Williams 2003、Müllerand Hagner(2002)、Erdogmus et al。など、TDDの関連する実証的研究とその高レベルの結果(セクション3関連作品)も簡単に要約しています。(2005)、Müllerand Tichy(2001)、Janzen and Seiedian(2006)。


2
Meta.StackOverflowの議論に従って、この質問を見つけた将来の人々だけでなく、質問者に関連する可能性がある追加の情報を論文から追加してもらえますか?
トーマスオーエンズ

2
@ThomasOwens、私は結論(「TDDは欠陥密度を40-90%削減する代わりに15-35%の開発時間を追加する」)元の質問<_ <

4
この投稿には、十分な情報が含まれていないというフラグが付けられています。私はまだ論文を読んでいませんが、回答の本文に追加の情報を追加したい人がいるようです。おそらく、研究で使用された特定の条件についてもっと議論しますか?
トーマスオーエンズ

すべての統計の99%は架空のものです。:Pしかし、実際にはコンテキストに関するものです。どんなチームで?平凡なJava開発者の大群?はい、TDDは生産性の向上に役立つと考えています。しかし、そもそも堅牢なコードを設計および評価するためのアーキテクチャスキルを持っていても、それ以上の助けにはならないことを意味するわけではありません。そして、はい、それがデザインに役立つと聞いたことがあります。ある程度まではそれはおそらく真実ですが、それでも未確認であり、根本的な問題であるIMOに対するバンドエイドです。
エリックReppen

ACM Digital Libraryからさらにいくつかの論文がリストされているか、そこの検索エンジンに使用するキーワードが追加されていればいいでしょう。アジャイルとTDDについて話すときは、より厳密な答えが必要です
ルドルフオラ

16

いくつかのテストを書くことにはいくつかの利点がありますが、ごくわずかです。そして、最初にテストを書くというアイデアは好きですが、実際のコードをデバッグするよりも、テストのデバッグに時間を費やして、自分の本当の意味を伝えるようにします。

私は過去3年間TDDに取り組んできましたが、私の経験は正反対です。単体テストを作成していなければ、コードをデバッグする単体テストの作成にかかる時間を短縮できます。

TDDを行うだけでなく、外部から作業します。つまり、最初にトップ/ GUIレイヤーTDDを実装します。最上層を実装すると、システムの次の層の要件が定義されます。この機能に必要なすべてのコードが実装されるまで、TDDなどを使用して開発します。多くの場合、このような機能を実装した後、実際のシステムでその機能をテストしてみると、初めて機能することがわかります。常にではありませんが、頻繁に。

また、実際のシステムで機能をスモークテストするのに2、3のユニットテストを実行するよりもはるかに長い時間がかかることを考えると、膨大な時間を節約できます。実際には、TDDを使用して機能を実装する方が、単体テストをまったく作成せずに機能を実装しないよりも迅速です。

ただし、単体テストの作成は、他のプログラミングスキルと同様に、習得して習得する必要があるスキルです。TDDを始めたとき、私はプログラミングで12年の専門的な経験があり、非常に熟練したプログラマーでした。システムコード用の大規模なテストスイートを書くのは簡単だと思いました。しかし、テストコードの量が増え、システムのさまざまな部分が変更され、既存のテストを変更する必要が生じたため、ユニットテストの構築と作成はそれ自体が習得し習得しなければならないスキルであることがわかりました。また、すべてのコードが同じようにテストできるわけではありません。効率的にテストできるようにするには、システムコードを非常に疎結合にする必要があります。実際にTDDを学習することで、システムコードをより疎結合にすることができました。

しかし、現在のTDDの効率は、ユニットテストの記述方法をマスターすることと、システムが実装されているテクノロジ(この場合はC#)をマスターすることの両方の組み合わせから得られます。

新しい技術を習得しながらTDDを行うのは難しい場合があります。たとえば、iPhoneプログラミングを少しやっていますが、かなりの量のユニットテストを書いているわけではありません。図書館。そのため、ユニットコードをどのように構成するか、システムコードをどのように構成してテスト可能にするかはわかりません。

しかし、実際のプロジェクトではどれだけうまく機能しますか?

私がここ数年取り組んでいるプロジェクトでは、コードを単体テストで十分にカバーする必要があるという要件がありますが、最初にテストを書いているのは私だけです。しかし、大規模なテストスイートは、システムをリファクタリングできるという自信を与えてくれ、テストスイートが合格した場合にシステムが正しく動作するという信頼を持っています。

しかし、残念なことに、テストの多くはシステムコードの後に​​記述されているため、テスト自体の多くは欠陥があります。つまり、実際にテストすることを意図していません。この私見は避けられません。コードを書くたびに、コードが意図したとおりに機能しない可能性があります。つまり、バグがあります。テストコードについても同じことが言えます。そのため、テストするコードが意図したとおりに機能していない場合でも、合格するテストを作成する可能性があります。

最初にテストを記述し、テストの失敗を取得するだけでなく、システムコードを実装する前に期待どおりのエラーメッセージでテストが失敗することを確認することで、単体テストコードのバグのリスクを減らします。

要約すると、私の経験では、TDDの技術を習得した後は、長期的には時間を節約するだけでなく、事前に時間を節約できます。しかし、経験豊富なプログラマーであっても、TDDの技術を習得するには時間がかかります。そして、さまざまなスキルを持つ開発者のチームがTDDの技術を習得するにはさらに時間がかかります。


9

私たちは大いに恩恵を受けました。

当社はティア1マーチャントです。つまり、年間600万件を超える支払い取引を処理しています。

支払いゲートウェイシステムには、数千のユニットテストと統合テストがあります。これらのテストは、支払いを処理する能力に自信を与えます。あなたはあなたの車のブレーキが機能することを確信したいですか?支払いを処理できないためにビジネスを失うことはないと確信しています。

コードカバレッジにより、その自信が得られます。もちろん、それだけでは十分ではありませんが、非常に良いスタートです。

支払いゲートウェイシステムのほとんどはTDDを使用して記述されています。いくつかの側面をテストするのはかなり難しかったため、コードカバレッジを犠牲にしてコーナーをカットすることにしました。最終的にこれらの問題に戻って対処します。

個人的には、テストを書く前にロジックを書くのは難しいと感じています。そうは言っても、TDDのように考え始めるには少し時間がかかりました。

Visa PCIリファレンス:http : //usa.visa.com/merchants/risk_management/cisp_merchants.html


3
「私たちは戻ってこれらの問題に最終的に対処します。」-おそらくそうではありません...恐ろしいバグであなたを非難しない限り、そうではありません。これらの領域は他のすべてのバックボーンになり、すべての設計を前進させます。リソースを投資してやり直したり、悪いことをするような変更を強制したりする人は誰もいないからです。毎回起こります:P
エドワードストレンジ

社内で何が起こっているかを私が話しているとき、あなたは推測しています。コミットするとき、70%のコードカバレッジでコードをコミットできます。これはCIリードによって常に増加しています。数か月以内に、コードカバレッジの最小しきい値がわずかな割合で増加します。その後、選択の余地はありませんが、さらにテストを導入します。
CodeART

7

テストは多くの場合、単なるやりすぎの方法と見なされる場合がありますが、特定の場合にはトラブルに見合うだけの価値があると思います。

私は約3か月間、学校向けのKiller Sudokuソルバーを開発してきました。多くの「戦略」を使用して、可能性と解決策を排除しています。実際には、可能性のエラーは致命的である可能性があり、数独を解決するための問題が発生する可能性があります。なぜなら、いくつかの可能性が取り除かれたとき、あなたはもうそれを試みず、それが解決策だった場合、プログラムは解決できないもうグリッド。

しかし、手動でテストするのは本当に難しいです。グリッドがあることを意味し、実際の世界の例ではどの戦略が何をしているのかを見ることができますが、これはあまりにも多くのデータを表すため、戦略が適用されるたびにすべてをチェックすることはできません。

また、特定のグリッドに適用される戦略は非常に「ランダム」です。つまり、特定のグリッドですべてを使用するわけではありません。

そこで、各戦略のテストを作成し、単純な状況(たとえば、2つのセルだけが既に可能性を排除しているなど)を使用して、すべてのセルの結果を確認しました。残念ながら、解決できないグリッドがあった1日を何時間も節約できました。何が問題なのかすでにわかっていたからです。


2
私はこの質問が最初にテストでもっと突っ込んでいると感じ、後の戦略を実装します。もちろん、テストはすべての可能性を自分でテストするのが面倒なアプリケーションのデバッグに役立ちます。
アレックスホープオコナー

6

TDDの利点は、実際のコードを書く前にコードを呼び出す方法を見つけ出すことです。

つまり、TDDはAPIの設計に役立ちます。

私の経験では、これによりAPIが改善され、コードが改善されます。


編集:私が書いたように、これは「私の経験」、つまり「現実世界のプロジェクト」を書いたときでしたが、残念ながらこれは世界に見せることのできないクローズドソースコードベースです。コメントから、これは実際に求められているものであり、そのようなプロジェクトの単なる存在の確認ではないことが理解できます。

また、私の個人的な経験では、要件が変更される傾向があるため、メンテナンスモードに入ると本当のメリットがあることもわかりました。よりクリーンなAPIにより、テストコードで新しい要件または変更された要件を簡単に表現でき、すべてのテストにより、コードがどのように呼び出され、何が返されるかを将来のメンテナーが非常に簡単に確認できます。

テストケースは仕様のバージョンを実行しており、APIを呼び出す方法を非常に簡単に確認できます。これはおそらく、正しいと確信している(これ以外の場合はテストが失敗する)ため、これまでに見た「HOW」ドキュメント(JavaDocのような「WHY」ドキュメントと比較してください)の最も便利な形式の1つです。

最近、アプリケーションの動作に影響を与える非常に大きなオプションのセットを備えたスクリプト可能なftpクライアントを維持する必要がありました。TDDは新機能用に最近導入され、大規模なテストスイートにより、使用された機能が期待どおりに機能することを確信しながら、修正プログラムを実行できます。言い換えれば、この移行は非常に迅速に成果を上げることが証明されました。


8
質問は実世界の例を必要とするため、この答えは完全に質問の横にあるようです。しかし、3人が「この答えは役に立つ」と思ったので、私は何かを見逃しているに違いありません。

3
同意しましたが、私は賛成票を投じる評判がありません。これは単なる「TDDにより良い結果が得られる」に過ぎず、メンテナンスでTDDから派生したプロジェクトの例ではありません。
ジェームズ

数人の人々が私に同意した今、私はあえて下票する。支持者、または著者は、ステップアップして、なぜこれが良い答えなのか教えてください。

@delnan「私はあえて下票」-興味深い言葉の選択。編集はあなたの好みに合っていましたか?

はい、気付いたので、今度は下票を削除しました。

5

テストに対する特定のアプローチがどれほど価値があるかは、開発中のシステムがミッションクリティカルであるかどうか、および他のミッションクリティカルなシステムがどれだけそれに依存しているかによって異なります。ウェブサイト用のシンプルなゲストブックスクリプトはミッションクリティカルとは考えられませんが、実行するウェブサイトがデータベースへのフィルタリングされていない入力を許可するバグによって潜在的に侵害され、そのサイトが重要なサービスを提供する場合、それは突然さらに多くなりますゲストブックスクリプトを徹底的にテストするために重要です。同じことがフレームワーク/ライブラリコードにも当てはまります。バグのあるフレームワークを開発する場合、そのフレームワーク機能を使用するすべてのアプリケーションにも同じバグがあります。

テスト駆動開発では、テストに関して安全性をさらに高めることができます。テストしたいコードと一緒に、またはテストの後でさえもテストを書くと、テストを間違えるという本当のリスクがあります。すべてのテストを最初に記述する場合、コードが内部でどのように機能するかはテストの記述に影響を与えないため、特定のエラー出力が正しいと考えるテストを不注意に記述する可能性は低くなります。

また、テスト駆動開発では、開発者がさらに多くの作業を行う必要がないため、テストが簡単なコードを作成することをお勧めします。テストが容易なコードは、理解、再利用、および保守が容易なコードである傾向があります。

そして、メンテナンスは本当にTDDの報酬を享受する場所です。ソフトウェアに費やされるプログラミング作業の大部分は、メンテナンス関連です。これは、ライブコードに変更を加えて、新しい機能を与えたり、バグを修正したり、新しい状況に適応させたりすることを意味します。このような変更を行う場合、変更が目的の効果を持っていることを確認する必要があります。さらに重要なのは、予期しないノックオン効果がないことです。コードの完全なテストスイートがある場合、行った変更が他の何かを壊していないことを簡単に確認できます。また、行った変更が他の何かを壊した場合、その理由をすばやく見つけることができます。利点は長期的です。

あなたはあなたの質問で次のように言った:

いくつかのテストを書くことにはいくつかの利点がありますが、ごくわずかです。そして、最初にテストを書くというアイデアは好きですが、実際のコードをデバッグするよりも、テストのデバッグに時間を費やして、自分の本当の意味を伝えるようにします。これはおそらく、テストコードがテストするコードよりもかなり複雑になることが多いためです。これが利用可能なツール(この場合はrspec)に不慣れであることを願っています。

これは、あなたがまったくテストを受けていないことを示唆しているようです。単体テストは非常に単純で、一連のメソッド呼び出しとそれに続くアサーションが予想される結果と実際の結果を比較するものであると想定されています。テストのバグは悲惨なものになるため、単純なものである必要があります。ループ、分岐、または他のプログラムがテストに制御をスローすると、テストにバグが導入される可能性が高くなります。テストのデバッグに多くの時間を費やしている場合は、テストが過度に複雑であり、テストを簡素化する必要があることを示しています。

テストを単純化できない場合、その事実だけでは、テスト対象のコードに何か問題があることを示唆しています。たとえば、クラスに長いメソッド、多数のif / elseif / elseまたはswitchステートメントがあるメソッド、またはクラスの現在の状態によって決定される複雑な相互作用を持つ多数のメソッドがある場合、テストは必然的に非常に複雑になります完全なコードカバレッジを提供し、すべての不測の事態をテストします。クラスに他のクラスへの依存関係がハードコードされている場合、コードを効果的にテストするためにジャンプする必要があるフープの数が再び増加します。

実行パスがほとんどない短いメソッドを使用して、クラスを小さく集中したままにして、内部状態を排除しようとすると、テストを簡略化できます。そして、これは問題の核心のようなものです。優れたコードは本質的に簡単にテストできます。コードのテストが容易でない場合は、おそらく何か問題があります。

単体テストを書くことは、長期的にはあなたに利益をもたらすものであり、それらを回避することは、後でトラブルを蓄積するだけです。あなたは技術的な負債の概念に精通していないかもしれませんが、それは金銭的な負債のように非常に機能します。テストを書いたり、コードをコメントしたり、ハードコードされた依存関係を書いたりすることは、借金をする方法です。早めにコーナーを切って時間を「借りる」ことで、締め切りに間に合うかもしれませんが、プロジェクトの早い段階で節約できる時間は貸し出しです。コードをクリーンアップしたり、適切にコメントしたり、テストスイートを構築したりせずに、毎日の作業に関心があります。それが長く続くほど、より多くの関心が蓄積されます。最終的に、コードが複雑な混乱になり、意図しない結果を引き起こすことなく変更を加えることができなくなることがわかります。

ユニットテストを早期に記述し、「技術的信用」の一形態として最新の状態に保つことを考えることができます。プロジェクトの早い段階でグッドプラクティスに従うことに時間を費やしています。この先見の明は、プロジェクトのメンテナンスフェーズに到達したときに興味を持ちます。変更を行う場合、変更の正確性と不要な副作用がないことを簡単に検証でき、更新をすぐに大騒ぎせずに入手できます。バグが見つかった場合は、バグを実行する新しい単体テストを追加して、コード内のバグを修正できます。次に単体テストを実行すると、バグが修正され、他の問題が発生していないことを確認できます。さらに、「回帰」を回避し、

TL:DR-はい、それらは現実の助けですが、投資です。利点は後で明らかになります。


1
私は数ヶ月前にこのロジックを購入しました。私はTDDの背後にあるアイデアが大好きです。私はその現実を少し混乱させているだけです。また、ここでも、TDDベースのプロジェクトを継承することで成果を上げた実際の例はありません。実際、たくさんの単体テストがあった古いコードベースに戻って、それは報われましたか?
ジェームズ

残念ながら、少なくとも以前の開発者から引き継いだコードのいずれかでは、他に誰もユニットテストを構築していないようです。彼らがいたなら、私の人生はずっと楽だったでしょう。リンクの本をチェックすることをお勧めします。実際の例がありますが、RailsではなくPHP用です。 amazon.com/...
GordonM

私は一般的な使用を非常に批判していますが、組み込み型または重要な金融システムでこのアプローチを使用することについて誰も責任を負いません。
エリックReppen

4

私は職場でTDDを頻繁に使用しています。私の経験では、追加の時間や労力を払わずにTDDを保存するため、TDDが正当化されます。

  • TDDを使用しているため、デバッグなどにかかる時間は大幅に短縮されます。テストに合格しない限り、生産的なコードが記述されているとは見なさないため、最初から機能します。

  • QAの報告するバグははるかに少ないため、リリース後にコードを修復するコストを節約できます。これは、TDDではテストなしでコードを記述できないため、コードカバレッジがはるかに優れているためです。

  • アプリケーションサーバー全体を起動する必要がないため、(生産的な)コードをより頻繁に、より速く実行できます。単体テストの開始は、桁違いに高速です。もちろん、生産的なコードを試してみたいときに、テストが既に実行可能である場合にのみ、それから恩恵を受けます。その後テストが行​​われると、この利点は失われます。

  • 私は手動テストをはるかに少なくしています。TDDを練習していない同僚は、新しいコードが実行されるポイントに到達するまで、アプリケーションをクリックするのに多くの時間を費やしています。バージョン管理にコミットする直前に、手動で1回だけテストします。

  • デバッガーを使用しても、アプリケーション全体よりもテストの実行をデバッグする方がはるかに高速です。

たぶん、あなたはユニットテストを回帰テストと考えています。それは彼らの目的の1つですが、それら開発のツールとして理解することは、彼らにとってより価値があります。


品質は無料です!
MathAttack

2
悪い品質は高価です!
ウルフギャング

3

他の利点(回答した他の人が言及したものに加えて)は、顧客受け入れテスターまたは(天国では禁止されている)実稼働ユーザーがバグを発見したときに有効になります。不具合があると思われるクラスのバグレポートをTDDスタイルのテストに変換します。失敗するのを見てください。修理する。それが通るのを見てください。これで、バグを修正したことがわかります。この手法により、時間を節約できました。


2

まあ、私は個人的に、仲間の開発者の2倍の速さで恩恵を受け、TDDをしないので彼らがするバグの半分以下を書くことを知っています。おそらく私よりも優れているはずの人々...私は彼らを少なくとも2倍以上に上回っています。

すぐには行けませんでした。私は、カフからハーネスを使わずにコードを書くのが得意です。この余分ながらくたをすべて書くのは大きな無駄のように思えた。ただし、以下を含むいくつかのことを行います(排他的ではありません)。

  • デカップリングと再利用に合わせた設計を強制する(すべてを単体テストで再利用する必要があります)。
  • 小さなチャンクとモジュールでコードを開発するためのプラットフォームを提供するため、単純な「コンパイルも入力も行う」種類のテストを実行する前に、すべてを把握して終了する必要はありません。
  • 予期しない機能の変更が必要になったときに変更を加えるための簡単なテストプラットフォームを提供します。

この後のビットの例は、私が現在取り組んでいるプロジェクトで、リードが突然0の理由で使用した通信プロトコルを完全に書き直すことにしました。それを他のすべてから切り離し、最後にそれを結び付けてテストを統合するステップまで完全に独立して作業することができたので、2時間でその変化に対応することができました。私の同僚のほとんどは、コードが切り離されず、どこでも、どこでも...すべてをコンパイルして...統合テスト...繰り返し、繰り返しているので、おそらく1日以上そこにいたでしょう...その方法ははるかに長くかかり、安定した場所ではありません。


2

答えはイエスです。私の会社では、20年以上にわたってC ++アプリケーションを開発しています。昨年、いくつかの新しいモジュールでTDDを導入し、欠陥率が大幅に減少しました。とても気に入ったので、何かを変更するたびにレガシーコードにテストを追加する人もいます。

さらに、バグを示すことなく、モジュール全体が最初から最後まで完成し、本番環境を通過しました(そして、これも重要なモジュールです)。そのため、開発は通常よりも高速でした。通常、そうでない場合は、モジュールが「完了」し、バグ修正のためのベータテストから4〜5回だけ返されるからです。これは大幅な改善であり、開発者も新しいプロセスに満足しています。

Rails TDDの多くは行っていませんが、C ++、C#、Java、Pythonで多くのことをしました。間違いなく機能していると言えます。私の推測では、十分な自信がないので、テスト名について考えるのに多くの時間を費やしていると思います。最初にテストを作成しますが、創造性を発揮させます...

本当にTDDのコツをつかめば、「このテストに名前を付けるのに... argh!」を少し気にし始めると、既に書かれたリファクタリングと適応を行うことに気づきました。現在の状況に合わせてテストします。

ヒントの時間

ヒント#1

したがって、私が最も役立つと思うヒントは、それほど心配しないことです。TDDの最も素晴らしい点の1つは、すでに書かれて機能しているものを変えることに勇気を与えることです。そして、それにはテストが含まれます。

ヒント#2

「OK、私は今このクラスに取り組んでいます...」のように、正しい方向に心を向けるために、単純な「canCreate」テストによって新しいクラスのテストを開始します。

その後、テストを追加しますが、一度に1つだけを追加し、作成する各テストを確認します。これは、その時点で頭に浮かぶ次の最も単純なケースです(30秒以内で考えてからタイムアウトします)その時点であなたが持っている最高のもので)。

そして覚える

既存のテストをリファクタリングしたり、廃止されたテストや冗長なテストを削除したりする心配はありません。多くの人はこれを理解していませんが、TDDでは実際に1の価格で2つのセーフティネットを取得します。テストは量産コード変更のセーフティネットですが、量産コードはテストのリファクタリングのセーフティネットでもあります。関係は相互です。実際には、密結合の良いケースです。

別のショットを与えます。Clean Code Casts、特にTDDに関するものを見ることをお勧めします。


1

実世界の重要な例:

データ構造変換関数を作成する必要がありました。入力はデータ構造(実際にはツリーのようなネストされたデータ構造)になり、出力は同様のデータ構造になります。私は心の中で実際の変化を視覚化できませんでした。(とにかく)TDDの主な利点の1つは、続行する方法がわからない場合のベビーステップの実施です(Kent Becksの「TDD by Example」を参照)。これがどこに行くのかわからなかったので、空の入力や些細な入力のような単純な基本ケースから始め、すべてをカバーするまで、より複雑なケースまで進めました。最終的には、動作するアルゴリズムとそれを証明するテストがありました。テストは、私の実装が現在動作していることを証明するだけでなく、後で何かを台無しにすることも防ぎます。


-1

ほとんどの開発者が生産性を向上させ、アプリケーションの欠陥を減らすのに役立つ万能の提案があるとは思わないので、一般的なアドバイスに盲目的に従うという考えは好きではありません。私の経験から言えば、品質を心配すればするほど、提供される新機能の量を失うことになります。そのため、品質と配信可能性のどちらを重視するかは、実際には製品と現在の戦略に依存します。おそらく、当面のより重要なことを戦略的に決定するのは堅牢性と配信可能性です。

この決定でさえ、黒でも白でもありません。ほとんどの場合、アプリケーションの一部は堅牢である必要がありますが、他の部分は必要ありません。どの部分に高品質が必要かを特定したら、それらの部分の高品質を確保したいので、テストの観点からそれらに注目する必要があります。

これまで述べてきたことはすべて、特に実装前にテストを作成するという意味ではTDDとは関係ありませんが、テスト済みのコードとテストを最初に作成することの利点を分けることが重要だと思います。

TDDであるかどうかに関係なく、テスト自体の利点を理解したら、テストでカバーしたいコードのテスト戦略について議論できます。一部の人々は、後でテストを書くと、テストのいくつかの条件を見逃すと主張しますが、それがあなたに当てはまるかどうかを評価するのはあなたであると信じています。確かに私には当てはまりません。

だから、ここでそれが私のためにどのように機能するかです。基本的に、テストを作成する2つの状況があります。それは、品質のみを向上させるか、何らかの機能の開発をスピードアップするかです。したがって、テストを作成する状況は、バックログに新しい機能がなく、アプリケーションのパフォーマンスを向上させるか、コードベースを単純化するか、テストスイートを改善するかを決定できる場合です。別の状況としては、実際のクライアントにバグが十分に大きな影響を与えるような、しっかりと機能するコードが必要です。さらにもう1つは、複雑なコードをテストするためのもので、作業中に簡単に壊れてしまいます。例として、多くのユースケースを処理するQueryBuilderクラスがコードベースにあり、バグを修正したり新しい機能を追加したりするときにそれらの一部を簡単に破ることができます。

最後に、最初にテストを記述すると、テストをまったく記述しないよりも早く機能を記述できる場合があります。このQueryBuilderは、このルールも適用された場合でもありましたが、TDDも最適なパスになるわけではありません。開発スピードを支援するTDDのもう1つの例は、たとえばExcel生成のテストです。一方、実際のアプリケーションでは、生成の特定の条件をテストするたびにいくつかの手順を実行する必要があります。または、機能をテストするためにいくつかのレコードを作成する必要があり、コードを手動でテストした後でそれらを手動で削除することが困難または不可能な場合。

そのため、開発中のコードをプログラムで(テストを介して)実行する手順を簡単に再現できる場合は、それを試してください。しかし、テストの作成が手動でのテストよりも複雑な場合は、品質に焦点を合わせるべきかどうか、またはバックログに多くのリクエストがあり、おそらく社内の誰かがそれをよく知って、現在のニーズと会社の戦略に応じて、どこに集中すべきかを知ってください。

理想的な世界では、すべてのコードがテストされますが、トレードオフがないふりをすることはできず、TDDが常に最良かつ唯一のパスであると想定できます。そこにあるすべてのベストプラクティスと同様に、あなたにとってより良いものではなく、あなたが働く会社にとって何が最善であるかに常に焦点を合わせる必要があります。自営業者になると、TDDが最善の道だと思うなら、TDDを常に実行することを自由に決定できます。会社がすべてのコードをテストする必要があると考えている場合、作成するすべてのコードのテストを作成する必要があります。ただし、ほとんどの場合、決断を下す前に、全体像を把握し、トレードオフを理解する必要があります。申し訳ありませんが、これは正確な科学ではなく、毎回従う必要がある簡単な(または難しい)定型的な答えはありません。

デザインパターンと同じです。それらがどのように機能し、なぜ作成されたか、どのような問題を解決し、どのような欠点があるかを理解してください。推論を理解することは、提案された解決策を覚えることよりもはるかに重要です。今日の高価な操作は、明日、他の技術で簡単に達成できるかもしれません。十分に確立されたソリューションの前提がもはや有効でない場合、おそらくソリューションは使用するのに最適ではありません。要件、利用可能な技術、または会社の戦略が変更された場合は、常にツールボックスを再評価する必要があります。その場合、許可のために最適なオプションとして採用するのではなく、最初に各パスを選択した理由を理解する必要があります。


これは、「最終的にペイオフが本物であることを示す例はありますか?TDDで設計/開発され、ユニットテストの完全なセットを持っているコードに実際に継承または戻った人はいますか?」実際に見返りを感じましたか?」
ブヨ

1
それは答えますが、あなたは私の意見を共有しないので、あなたはそれに-1を与えます:)基本的にTDDの値を表示しようとしないだれでもあなたの観点から望ましくない答えを与えるでしょう;) 。あなたはTDD福音宣明者ですよね?:)ところで、著者の本当の質問は、TDDが報われるかどうかです。それに答えるためにTDDを練習する必要はありません。FortranはWebアプリを書くことで利益を上げますか?答える前に試したことはありますか?
ローゼンフェルド

私はTDDについて意見がありませんし、票を好き嫌いとして使用しません(Facebookではなく、質問と回答のサイトです)。私の読書ごとに、この「答えは」単に質問が正にも負にも、一切尋ね対応していません
ブヨ

私の観点からは、これは「nginxでXをどうやってやるの?」のような技術的な質問ではありません。そのような質問には正しい答えがありますが、著者がTDDについて他の人の意見や価値があるかどうかを実際に知りたい場合は、このような質的および主観的な質問には答えません。それが私の視点を示すための私の試みでした。すべての回答が私の個人的な意見のように見えるので、回答がどのように正しいものになるかはわかりません。TDDが価値があるかどうかを効果的に測定することはできません。それを試みる記事は根本的に間違っています。
ローゼンフェルド

「このサイトはすべてのツアーで 回答を得ています。ディスカッションフォーラムではありません...」
gnat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.