通常、私はコピーアンドペーストやその他のあらゆる悪い習慣を使用して、単体テストを一緒に投げます。単体テストは通常、見苦しくなり、「コードのにおい」でいっぱいになりますが、これは本当に重要ですか? 「本当の」コードが「良い」ものである限り、私はいつも自分に言い聞かせます。さらに、単体テストでは通常、スタブ機能のようなさまざまな「臭いハック」が必要です。
不十分に設計された(「悪臭のする」)単体テストをどの程度心配すべきですか?
単体テストの匂いは重要ですか?はい、間違いなく。ただし、ユニットテストは目的が異なり、設計に通知する一連のテンションが異なるため、コードの匂いとは異なります。コードの多くのにおいはテストに当てはまりません。私のTDDの考え方を考えると、ユニットテストの匂いはコードの匂いよりももっと重要であると私は実際に主張します。
ここにいくつかの一般的なユニットテストの匂いがあります:
匂いの重要性は、匂いがデザインやその他の根本的な問題、つまり「煙があるところ、火があるところ」の有用な指標であることです。テスト臭を探すだけでなく、根本的な原因も探します。
一方、単体テストの優れたプラクティスは次のとおりです。
心配します。単体テストを作成して、コードが期待どおりに動作することを証明します。自信を持ってすばやくリファクタリングできます。テストが壊れやすく、理解が難しい場合、または維持するのが困難な場合は、失敗したテストを無視するか、コードベースの進化に伴ってテストをオフにして、そもそもテストを書くことの多くの利点を無効にします。
数日前 The Art of Unit Testing を読み終えたところです。著者は、本番用コードを実行するときと同じように、単体テストに注意を払うことを推奨しています。
私は不十分に書かれた、保守不可能なテストを直接体験しました。自分で書いたものもあります。テストがお尻を維持するのが面倒なら、それが維持されないことは事実上保証されています。テストがテスト対象のコードと同期しなくなると、それらは嘘と偽りの巣になっています。単体テストの要点は、私たちが何も壊していない(つまり、信頼を生み出す)ことを確信させることです。テストが信頼できない場合、それらは役に立たないよりも悪いです。
単体テストが実際にコードを「ほとんどの」ケースでテストする限り。 (考えられるすべての結果を見つけるのが難しい場合があるため、意図的に最も言った)。 「臭い」コードは個人的な好みだと思います。私は常に、ジャンクを掘り下げて何が何であるかを理解しようとするのではなく、コードを読んで数秒で理解できる方法でコードを作成します。特にあなたがかなりの時間の後にそれに戻ってきたとき。
結論-そのテスト、それは簡単だと思います。 「臭い」コードと混同したくはありません。
間違いなく。一部の人々は、「どんなテストもまったくテストよりも優れている」と言います。私は強く同意しません-間違って書かれたテストは開発時間を圧迫し、そもそも「壊れた」テストを修正するのに何日も無駄になってしまいます。現在のところ、テストを負担ではなく価値あるものにするために焦点を当てている2つの点は次のとおりです。
メソッド(howではなく、結果(whatが発生する)をテストする必要があります-)起こります)。テストのセットアップは、実装から可能な限り切り離す必要があります。絶対に必要なサービス呼び出しなどの結果のみをセットアップしてください。
テストでもう少し繰り返しを許可してもかまいません。テストを読みやすくするためには、通常、本番コードでは許可しません。これと上記の保守性とのバランスを取ってください。テストの内容を明確にしてください。
結論として、あなたは「臭い」テストに非常に関心を持つべきです-それらは結局あなたの時間の浪費に終わり、価値を提供することができません。
あなたは言った:
単体テストは通常、スタブ機能のようなさまざまな「臭いハック」を必要とします。
Mockingフレームワークを使用するなど、いくつかの単体テスト手法を読むことで間違いなくあなたの生活をずっと簡単にすることができるように思えます。私は非常に強くお勧めします ユニットテストの芸術 、これは上記とはるかにカバーしています。長い間、不十分に記述された、保守不可能な「悪臭のする」テストに苦労した後、私はそれが啓発的であることに気付きました。これは、私が今年行った中で最高の時間の投資の1つです。
2つの質問:
ユニットテストで繰り返し行われるタスクを処理する方法は、最も一般的にはセットアップコードとティアダウンコードです。基本的に、テストセットアップメソッドとテストティアダウンメソッドがあり、すべての単体テストフレームワークがこれをサポートしています。
単体テストは小さく、簡単に理解できる必要があります。そうでない場合、テストが失敗すると、かなり短い期間で問題をどのように修正しますか。コードに戻る必要がある場合は、今後数か月間は自分で簡単にできるようにします。
ゴミの臭いがし始めたら、それを取り出す時です。テストコードは、製品コードと同じくらいクリーンでなければなりません。お母さんに見せてくれませんか?
これを正当な質問として扱う方法さえ理解するのにしばらく時間がかかったので、私はほとんど答えを提出しませんでした。
プログラマーが「ベストプラクティス」に携わる理由は、美的理由や、「完璧な」コードを望んでいるためではありません。それは彼らが時間を節約するからです。
それで、あなたの質問(私の観点から)は、自分の時間を節約するか、私の時間を無駄にするコードを書くべきですか?
その質問に対して私は言うことができます、あなたの時間はどのくらい重要ですか?
参考までに:スタブ、モック、およびモンキーパッチはすべて正当な用途があります。それらは、その使用が適切でない場合にのみ「におい」を発します。
ここに他の答えに加えて。
単体テストの質の低いコードは、単体テストスイートに限定されません。
単体テストで満たされる役割の1つはドキュメントです。
ユニットテストスイートは、APIがどのように使用されることが意図されているかを確認するための場所の1つです。
APIの呼び出し元がユニットテストスイートの一部をコピーする可能性は低くないため、不正なテストスイートコードが他の場所のライブコードに感染します。
私は特に、ユニットテストを堅牢にしすぎないようにしています。堅牢であることを理由にエラー処理を開始する単体テストを見てきました。最終的には、キャッチしようとしているバグを飲み込むテストになります。ユニットテストはまた、物事を機能させるためにかなり頻繁にファンキーなことをしなければなりません。リフレクションを使用してプライベートアクセサーの全体的なアイデアについて考えてみてください...実稼働のコードでそれらのすべてを見た場合、私は10回のうち9回心配します。何がテストされているかを考えるためにより多くの時間を費やす必要があると思いますコードの清潔さよりも。大規模なリファクタリングを行う場合は、テストをかなり頻繁に変更する必要があるので、それらを一緒にハックし、所有権の感触を少し減らし、時が来たらそれらを書き直したり再作業したりする動機を高めてみませんか?
重度の低レベルのカバレッジを行う場合、深刻な変更を行う場合、製品コードと同じくらい多くの時間をテストコードに費やすことになります。
テスト設定の複雑さに応じて、コードはさらに複雑になる場合があります。 (たとえば、httpcontext.currentと、偽のモンスターを正確に構築しようとする恐ろしいモンスターの例)
製品が既存のインターフェイスに重大な変更を加えることがほとんどなく、ユニットレベルの入力の設定が非常に簡単なものでない限り、実際の製品としてのテストの理解について心配する必要があります。
コードのにおいは、コードの問題であり、後で変更または理解する必要があります。
そのため、特定の単体テストに「近づく」必要がある場合は、コードの臭いを修正する必要がありますが、以前は修正しないでください。