web-dev-qa-db-ja.com

TDDと単体テスト

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

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

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

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

[〜#〜]編集[〜#〜]

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

フォローアップ

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

117
Walter

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

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

76
Justin Niessner

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

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

27
Kaleb Brasee

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

16

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

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

12
Aaron Digulla

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

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

12
Diego Dias

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

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

9
Wayne Molina

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

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

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

6
Pascal Thivent

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

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

4
Dai Bok

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

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

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

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

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

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

3
kriss

単体テストの最も有用な側面の1つは、すでに機能しているコードの継続的な正確性を保証することです。意のままにリファクタリングできる場合は、IDEでコンパイル時エラーを通知し、ボタンをクリックして、潜在的なランタイムエラーをテストで発見できるようにします。以前は些細なコードブロックに到着することもあります。 、それからあなたのチームはTDDを高く評価し始めていると思うので、既存のコードのテストから始めることは間違いなく便利です。

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

3
David Berger

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

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

余談ですが [〜#〜] bdd [〜#〜] も興味深いかもしれません

3
danswain

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

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

3
Michael Nash

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

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

2
Chris Welsh

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

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

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

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

2
rsp

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

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

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

2
John Sonmez

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

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

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

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

1
Doug Knesek