TDDと単体テストの比較[終了]


117

私の会社はコードを単体テストするのがかなり新しいです。私はTDDと単体テストについてしばらく読んでおり、それらの価値を確信しています。私は、TDDがプログラミング方法について学習し、考え方を変える努力の価値があることをチームに納得させようとしましたが、それは苦労です。これは私の質問に私をもたらします。

TDDコミュニティには、テストの作成とコードの作成に非常に熱心な人がたくさんいます(そして私も彼らと一緒にいます)が、TDDに苦労しているチームにとって、妥協はまだ追加の利点をもたらしますか?

コードが記述されたら(おそらくコードをチェックインするための要件として)、チームにユニットテストを記述させることに成功する可能性があり、私の前提は、これらのユニットテストの記述にはまだ価値があるということです。

苦労しているチームをTDDに取り込む最善の方法は何ですか?それに失敗したとしても、コードが書かれた後でも、単体テストを書く価値はありますか?

編集

私がこれから取り除いたのは、コーディングプロセスのどこかでユニットテストを開始することが重要であることです。チームのコンセプトを取り上げた人は、最初にTDDとテストに向けて動き始めます。皆様のご意見ありがとうございます。

ファローアップ

私たちは最近、新しい小さなプロジェクトを開始し、チームのごく一部がTDDを使用しました。残りはコードの後に​​ユニットテストを作成しました。プロジェクトのコーディング部分をまとめた後、コードの後のユニットテストの記述は、TDDコーダーが既に実行されており、より堅実なコードを使用していたことに驚いていました。それは懐疑論者に勝つための良い方法でした。私たちはまだ先に多くの成長する苦痛を持っていますが、意志の戦いは終わったようです。アドバイスをくれた皆さん、ありがとう!


1
このスレッドが役立つかもしれません:stackoverflow.com/questions/917334/should-i-use-tdd
Randolpho

29
フォローアップのための+1。それは素晴らしい話です。
Carl Manaster、2010

回答:


76

チームがTDDの実装に困惑しているが、ユニットテストを以前に作成していなかった場合は、コードを記述した後でユニットテストを作成することから始めます。コードの後に​​書かれた単体テストでさえ、単体テストがないよりも優れています!

ユニットテスト(およびそれに伴うすべて)に習熟したら、最初にテストを作成し、次にコードを作成してもらうことができます。


3
チームがこれまでユニットテストを作成していなかったのは正しいことです。これは、完全なTDDへの良い足掛かりのように感じます。
ウォルター

これにはこれ以上同意できません。実際、私は数か月前に同様の質問に対して同様のことを書いたと思います。どこだ…ああ!stackoverflow.com/questions/917334/should-i-use-tdd/…–
Randolpho

27

コードが書かれた後にユニットテストを書く価値は絶対にあります。コードがテスト可能に設計されておらず、コードが複雑すぎたために、多くの場合困難な場合があります。

チームをTDDに導入するには、移行期間または長期的には「開発中のテスト」の代替方法を提供するのが良いと思います。彼らには、彼らにとって自然に見えるコードのTDDセクションに励まされるべきです。ただし、テストファーストに近づくのが難しいと思われるコードのセクション、または非アジャイルA&Dプロセスによって事前に決定されたオブジェクトを使用する場合、開発者はコードの小さなセクションを記述し、それをカバーするテストを記述するオプションを提供できます。コード、およびこのプロセスを繰り返します。コードを記述した直後に一部のコードの単体テストを作成する方が、単体テストをまったく作成しないよりも優れています。


16

100%のテストカバレッジとTDDを備えた50%完成したライブラリよりも、「コードファースト、テストアフター」で50%のテストカバレッジと100%完成したライブラリがあるほうが私の控えめな意見です。しばらくすると、仲間の開発者は、自分が書いたすべてのpublicコードのテストを書くのが楽しくて教育的になるので、TDDが開発ルーチンに忍び込みます。


3
私はあなたのドリフトを手に入れますが、50%のテストカバレッジで「100%完成したライブラリ」に警戒しています...一部のテストでカバーされていないすべてのコードには少なくとも1つのバグが含まれているという私の経験からです。または別の言い方をすると、人々は、いくつかのより多くのテストから本当に恩恵を受けるコードのテストを書くことを避ける傾向があります:)
Aaron Digulla 2009年

2
まあ、別の言い方をすると、リリースされたバグのあるコードは、永遠に衰退する完璧なコードよりも優れています。もちろん例外がある NASAのが、ほとんどの部分は、そこにあなたのコードを取得します。リリース後もテストを追加できます。
jcdyer 2009年

3
「100%完成したライブラリ」とはどういう意味ですか。バギーならそれは完全だと思いますか?完了の定義にテスト済みを含めませんか?
Pascal Thivent 2009年

10
テストされることは、バグのない十分な条件ではありません
fa。

2
テストカバレッジツールで測定されるテストカバレッジは、両刃の剣です。IUTのすべてのメソッドを呼び出すことによってそれが達成されても、テストが実際には壊れそうな動作をテストしていない場合、開発者や他の利害関係者は誤った安心感を抱くでしょう。組織内のTDDへの全体的な動きは、重要な動作がテストされていないにもかかわらず、100%のテストカバレッジを持っている場合に直面する可能性があります。最も重要なことは量ではなく質です。
Doug Knesek 2009年

12

私はこれをカレンダーで読んだだけです。「すべてのルールは、最大限に実行されると、ばかげたり、さらには危険になったりします。」だから私の提案はそれについて信心深くないことです。チームのすべてのメンバーは、テストに関して「正しい」と感じることのバランスを見つける必要があります。このようにして、チームのすべてのメンバーが最も生産的になります(たとえば、「なぜこのsti ****テストを記述しなければならないのですか?」と考える代わりに)。

したがって、いくつかのテストはどれよりも優れており、コードの後のテストはいくつかのテストよりも優れており、コードの前のテストはコードの後よりも優れています。しかし、各ステップにはそれぞれのメリットがあり、小さなステップでも眉をひそめるべきではありません。


「彼らが感じること」開発者として、私は自分の感情を通じて自動化された単体テストを実行したい(正しい)欲望を覚えていません。手動のものだけです。私は、テストから興奮することに欠けている私だけではないと思います
Gennady VaninГеннадийВанинDec

@ vgv8:つまり、テストが役に立たないということです。これには多くの理由があります。より深く掘り下げることをお勧めします。どのプロジェクトも、良いテストの恩恵を受け、悪いテストに悩まされます。良いテストの作成を開始すると、その時点から、それ以上の作成を止めることはできなくなります。
Aaron Digulla

私にとって正しいと感じるのは、プログラミングユニットが何をすべきかをカバーするテストのレベルであり、機能レベルから:ユーザーが通常実行していること。「報告されたバグ」と呼ばれる悪い結果も含まれます。バグが確認された場合、少なくとも1つのテストが作成されます。プロジェクトが大きくなり、チームが大きくなるほど、これはより重要になります。
DaFi4

12

TDDはデザインについてです!したがって、それを使用すると、コードのテスト可能な設計が確実になり、テストの記述が容易になります。コードが書かれた後にテストを書く場合、それらはまだ価値がありますが、私見あなたはおそらくテスト可能な設計を持っていないのであなたは時間を無駄にするでしょう。

TDDを採用するようにあなたのチームを説得するために私があなたに与えることができる1つの提案は、Mary Lynn MannsとLinda RisingによるFearless Change:Patterns for Introducing New Ideasで説明されている手法のいくつかを使用することです。


3
+1:テスト駆動開発とは、設計がテストの考慮事項によって駆動されたことを意味します。
S.Lott、2009年

+1。ユニットテストは後で役立ちますが、ユニットテストを事前に記述しないと、「テスト可能な設計」の利点が失われます。
Noufal Ibrahim、2010

9

IMOよりもテストが初めての場合は、すでに記述されているテストコードから始めて、徐々にテストを記述してから最初にテストを記述します。TDDを学び、ユニットテストを初めて行う人として、完全な180を実行し、コードの前にテストを作成するように考え方を変えるのは難しいので、私が取っているアプローチは50-50のミックスのようなものです; コードがどのように見えるかが正確にわかったら、コードを記述してから、それを検証するためのテストを記述します。完全に確信が持てない状況の場合は、テストから始めて、後戻りします。

また、テストを満たすコードを書くのではなく、コードを検証するテストを書くことには何の問題もないことも覚えておいてください。チームがTDDルートに進もうとしない場合は、強制的にTDDルートに強制しないでください。


6

コードが記述されたら(おそらくコードをチェックインするための要件として)、チームにユニットテストを記述させることに成功する可能性があり、私の前提は、これらのユニットテストの記述にはまだ価値があるということです。

(テストがいつ作成されたかに関係なく)単体テスト済みのコードに価値があるという事実については間違いなく、「コードは単体テスト済み」を「完了の定義」に含めています。テストする限り、人々はTDDを使用してもしなくてもかまいません。

バージョン管理に関しては、ユニットテストポリシー(つまり、コードのコンパイルとビルド、すべてのユニットテストに合格)で「開発ブランチ」を使用するのが好きです。機能が完了すると、開発ブランチからトランクに公開されます。つまり、トランクブランチは「完了ブランチです。」(トランクにジャンクはありません!)であり、 出荷可能なポリシー(いつでもリリースできる)があり、より厳格で、「単体テスト」よりも多くのものが含まれています。


4

これは、チームがそれを信じ始める前に独自の成功を収めなければならないものです。私が気にかける人のために、私のnUnitエピファニーについて怒鳴ります。

約5年前、プロジェクトで作業しているときにnUnitを発見しました。V1.0はほぼ完成しており、この新しいツールを試すためにいくつかのテストを作成しました。新しいチームだったため、多くのバグがありました(明らかに!)、締め切りが厳しく、期待が高かった(聞き覚えがあるでしょうか?)など。チームを少し再編成し、2人の開発者を割り当てました。私は彼らのために1時間のデモを行い、私たちが書いたすべてのものにテストケースが必要であると伝えました。ユニットテストというより多くのコードを記述していたので、1.1開発サイクルの間、チームの残りの部分の後ろを常に走っていました。最終的にはより多くの作業が行われましたが、これは見返りです-テストに取り掛かったとき、コードにバグがまったくありませんでした。他のすべての人がバグをデバッグして修復するのを支援しました。死後、バグの数が表示されたとき、

私はあなたが成功への道をテストできると思うほど馬鹿ではありませんが、ユニットテストに関しては私は真の信者です。プロジェクトはnUnitを採用し、1つの成功の結果として、すぐにすべての.Netプロジェクトのために会社に広がりました。V1.1リリースの合計期間は9 dev週間だったので、一晩で成功することはありませんでした。しかし、長期的には、私たちのプロジェクトと私たちがソリューションを構築した会社にとって、それは成功を収めました。


「プロジェクトはnUnitを採用し、すぐにすべての.Netプロジェクトのために会社に広まりました」そして、1つの製品/プロジェクトにC#、Java、C ++、SQL Serverコードがある場合はどうすればよいですか?
Gennady VaninГеннадийВанин

わからない...本番環境にデプロイする前にすべてのコンポーネントをテストする方法を見つけますか?単体テストは、それが稼働する前の包括的なテスト計画の1つの側面にすぎません。どのシナリオでも穴を開けることができます。
返金不可返品不可2018

4

テスト(First、While、またはAfter)によってベーコンが節約され、生産性と信頼性が向上することは間違いありません。採用をオススメします!

私は似たような状況にありました。私は「初心者」の開発者でしたので、コントリビューションがビルドを壊してしまったという事実のためにチームプロジェクトで作業するとき、私はしばしば苛立ちました。私が責任があるのか​​、場合によっては誰が責任を持つのかわかりませんでした。しかし、私は仲間の開発者たちにも同じことをしていることをもっと心配していました。この実現は、いくつかのTDD戦略を採用する動機となりました。私たちのチームは愚かなゲームとルールを持っています。すべてのテストに合格するまで家に帰ることはできません。または、テストなしで何かを提出すると、「ビール/ランチ/その他」をみんなに購入しなければならず、TDDがさらに楽しくなります。


3

単体テストの最も有用な側面の1つは、すでに機能しているコードの継続的な正確性を保証することです。自由にリファクタリングできる場合は、IDEにコンパイル時のエラーを通知させてから、ボタンをクリックして、潜在的なランタイムエラーを検出できるようにします-以前はささいなコードのブロックに到着することもありますが、チームが見つかると思いますTDDに感謝し始めました。したがって、既存のコードのテストから始めることは間違いなく役立ちます。

また、率直に言うと、TDDから始めるよりも、作成したコードをテストしてテスト可能なコードを作成する方法について詳しく学びました。最終目標を達成し、テストを許可するコントラクトを考えようとすると、最初は抽象的すぎる可能性があります。しかし、コードを見て「このシングルトンは依存性注入を完全に台無しにし、これをテストすることを不可能にします」と言うと、どのパターンがテストをより簡単にするかについての理解を深め始めます。


3

まあ、最初にテストを書かなければ、それは「テスト駆動」ではなく、単にテストです。それ自体に利点があり、コードベースを既に持っている場合は、テストを追加することはTDDではなく単にテストであっても確かに便利です。

最初にテストを書くことは、コードを書く前に何をすべきかに焦点を当てることです。はい、それを行うテストも受けますが、それは良いことですが、それが最も重要なポイントでさえないと主張する人もいます。

私がやろうとしていることは、TDDを使用して、このようなおもちゃプロジェクト(コーディング道場、カタを参照)についてチームをトレーニングすることです(経験豊富なTDDプログラマーにこのようなワークショップに参加してもらうと、さらに良いでしょう)。メリットがわかると、実際のプロジェクトにTDDを使用します。しかし、その間彼らを強制しないでください、彼らが彼らがそれを正しくしないであろう利点を見ないなら、彼らはそれをしません。


3

コードを記述する前に設計セッションがある場合、または設計ドキュメントを作成する必要がある場合は、ユニットテストをセッションの具体的な結果として追加できます。

これは、コードがどのように機能するかに関する仕様として機能します。設計セッションでペアリングを促し、特定のシナリオで何かがどのように機能し、何をすべきかについて人々に話してもらいます。エッジケースとは何か、明示的なテストケースがあるので、たとえば、null引数が指定された場合に誰が何をするかがわかります。

余談ですが、BDDも興味深いかもしれません


私はBDDを知りませんでした。それについてもっと読む必要があります。
ウォルター

3

TDDの結果、コードの記述が少なくなる1つまたは2つの例を示すことで、いくつかの牽引力が見つかる可能性があります。テストに合格するために必要なコードのみを記述するため、ゴールドプレートへの誘惑やYAGNIへの取り組みは抵抗しやすくなります。記述していないコードは、保守やリファクタリングなどを行う必要がないため、TDDの概念の販売に役立つ「実際の節約」になります。

時間、コスト、コード、および保存されたバグの点で価値を明確に示すことができれば、それはより簡単な販売であることがわかるかもしれません。


2

JUnitテストクラスの構築を開始することが開始方法であり、既存のコードの場合、それが開始する唯一の方法です。私の経験では、既存のコードのテストクラスを作成すると非常に便利です。これが時間をかけすぎると経営陣が考えている場合は、対応するクラスにバグが含まれていることが判明した場合、またはクリーンアップが必要な場合にのみ、テストクラスを作成することを提案できます。

メンテナンスプロセスの場合、チームを一線を越えるアプローチは、バグを修正する前にJUnitテストを記述してバグを再現することです。

  • バグが報告されています
  • 必要に応じてJUnitテストクラスを作成する
  • バグを再現するテストを追加する
  • コードを修正する
  • テストを実行して、現在のコードがバグを再現しないことを確認します

この方法でバグを「文書化」することで、それらのバグが後で忍び込むのを防ぐことができると説明できます。これは、チームがすぐに体験できるメリットです。


2

私はこれを多くの組織で行ってきましたが、TDDを開始して実行するには、ペアプログラミングをセットアップするのが最善の方法です。TDDを知っていると期待できる人が他にいる場合は、2人で分割し、他の開発者とペアにして、実際にTDDを使用していくつかのペアのプログラミングを行うことができます。そうでない場合は、チームの他のメンバーに提示する前に、これを行うのを助ける誰かを訓練します。

単体テスト、特にTDDの主なハードルの1つは、開発者がそれを行う方法を知らないため、時間の価値があるかどうかを理解できないことです。また、最初に開始したときは、速度がはるかに遅く、メリットが得られないようです。それはあなたがそれが得意なときにだけあなたに本当にあなたに利益を提供しています。ペアのプログラミングセッションを設定することで、開発者はすぐにそれを学び、より早く上手に習得することができます。さらに、一緒に仕事をしていると、彼らはすぐにその恩恵を受けることができます。

このアプローチは、過去に何度も私に役立ちました。


2

TDDの利点を発見する強力な方法の1つは、おそらくパフォーマンス上の理由から、いくつかの既存の機能を大幅に書き換えることです。既存のコードのすべての機能をカバーする適切なテストを実行する一連のテストを作成することで、変更が安全であるという完全な自信を持って、心のコンテンツにリファクタリングする自信が得られます。

この場合は、設計またはコントラクトのテストについて話していることに注意してください。実装の詳細をテストする単体テストは、ここでは適していません。しかし、繰り返しになりますが、TDDは実装の前に記述されることになっているため、定義によって実装をテストすることはできません。


1

TDDは、開発者がより良いコードを生成するために使用できるツールです。テスト可能なコードを書く練習は、テスト自体と同じくらい価値があると思います。テスト目的でIUT(テスト対象の実装)を分離すると、コードを分離するという副作用があります。

TDDはすべての人に適しているわけではなく、チームにそれを選択させる魔法はありません。リスクは、テストの価値を知らない単体テストの作成者が多くの低価値テストを作成することです。これは、組織内のTDD懐疑論者にとって大砲となります。

私は通常、自動受け入れテストを交渉不可能にしていますが、開発者がTDDをそれに適したものとして採用できるようにしています。私は経験豊富なTDDersに残りのトレーニング/メンターをさせ、何ヶ月にもわたって例を挙げてその有用性を「証明」します。

これは、技術的変化だけでなく、社会的/文化的変化でもあります。

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