私のプロジェクトは、単体テストを可能にするのに十分分離されていると思います。しかし、ユニットテストを価値のあるものにするために、プロジェクトはクラスと機能の点でどれほど大きい必要がありますか?
私たちは皆間違いを犯し、誰も完璧ではありませんが、私自身は、小さなプロジェクトのエラーをステップスルーで処理するためのまともなプログラマーであると考えています。または、プロジェクトのサイズに関係なく、ユニットテストは必要不可欠なものですか?
私の経験では、ユニットテストの必要性を考慮するには、oneクラスとone関数で十分でした。
class Simple {
boolean reallySimple() {
return true; // how do we make sure it doesn't change to false?
}
}
class SimpleTest {
void assertReallySimple() {
// ensure reallySimple return value isn't changed unexpectedly
UnitTestFramework.assertTrue(new Simple().reallySimple());
}
}
私は「すべてを単体テストしなければならない」という考えには決して賛成していませんが、確かにそこにいる人はいます( gnatの答え を参照)。
私に関する限り、単体テストの主な利点は次のとおりです。
基本的に、これらの要因に対するテストを作成して維持するのにかかる時間を比較検討する必要があります。
通常、1で十分です。私の経験では、コードの95%以上が遅かれ早かれ修正されます。
簡単です。一度実行した後にプログラムを破棄する場合は、単体テストは必要ありません。
これが過度に思われる場合は、代替手段の意味を検討してください。ユニットテストで支払えないサイズがいくつかある場合は、「マジックサイズにまだ到達したか?テストの記述を開始すべきか?」と考え続ける必要があります。現在、プログラマーは未来を予測することで悪名高く、彼ら自身のスキルを判断することで悪名高い。 1か月待たなくても、今あなたにとって非常に明確に見えるコードは理解できなくなります。あなたが絶対的に、確実に確実であるプロジェクトは、再び使用されることはなく、前に何かを解決した方法を調べたいと思う可能性がわずかにあるだけで、willが再度要求されます。変更リクエストを受け取ります。
したがって、テストが役立つかどうかを誤って判断する可能性が非常に高く、テストが必要になり始めたとき、実際にテストする正確なセマンティクスが何であるかを100%確信していません。些細な1回限りのプログラムを除いてすべてが単体テストから利益を得ると私は信じているので、二度と実行されないテストに費やす労力のコストは、テストされておらず、理解されていないコードを拡張するリスクに対して無視できると考えています。
しばらく前に私は素敵な投稿を見つけました: なぜユニットテストは開発をスピードアップするのですか 。質問に答えるのに役立ちます。
...コードベースが大量のユニットテストで提供された場合はどうでしょうか。次のようなセット:「すべてのテストが成功した場合でも、コードが実行すべきことを保証します」。テストが失敗した場合は、一部の動作が壊れていることを正確に示します。これは素晴らしいです。コードを変更して、コードが本来の機能を果たす場合は、迷うことなく必要なものを追加できます。テストを実行するだけで、信頼できます。これは、ソフトウェアエンジニアとして素晴らしい世界です。私はもっと速く進むことができることに気づきました...
私は「信仰」を持っています。
これはおそらく、ユニットテストがエンタープライズコンテキストでの開発をスピードアップする最も重要な理由です。
すべてのテストに合格した場合でも、すべてが機能することを信頼できます。テストが失敗した場合、彼らは問題がどこにあるのか正確に指摘します...
...高いユニットテストカバレッジと良いユニットテストが必要です-)。これらの条件が尊重されると、新しい機能を追加するための労力はアプリケーションのサイズにほとんど依存せず、長い目で見ればそれがスピードアップするという状況になります。開発。
Michael Feathersは彼の著書の1つで、コードの変更を処理する2つの方法を紹介しました。
コードベースの大きさは関係ありません。
Kent Beck によるスタックオーバーフローの質問への回答 ユニットテストの深さはどれくらいですか? によると、誤りがちなコードをテストする必要があります。
通常、ある種の間違い(コンストラクターでの間違った変数の設定など)を行わない場合は、テストしません。
ユニットテストは時間を節約し、改善するために実装されています:
プログラムの比較的複雑な部分の単体テストを作成する必要があります。
ユニットテストを今すぐ作成しても将来的に時間を節約できないと確信している場合は、それをスキップできます。しかし、あなたは決して知りませんし、個人的には、単体テストを作成せずにすべてのテストを手動で行う方が(時間、お金、神経という意味で)安いケースは考えられません。
テストせずにコードを書く場合を除いて、常にテストのコストが発生します。
単体テストがある場合とない場合の違いは、手動でテストする場合のコストと比較した、テストを作成するコストと実行するコストの違いです。
単体テストを作成するコストが2分で、単体テストを実行するコストが実質的に0であるが、コードを手動でテストするコストが1分の場合、テストを2回実行しても中断します。
何年もの間、コードの単体テストを作成するのに十分な時間がないという誤解を受けていました。私がテストを書いたとき、それらは肥大化した重いものであり、ユニットテストを書くべきだと思うようになっただけですknew必要なときだけです。
最近、私は Test Driven Development を使用するよう勧められましたが、それは完全な啓示であることがわかりました。時間がないと確信しましたnot単体テストを作成する。
私の経験では、テストを念頭に置いて開発することで、よりクリーンなインターフェイス、より焦点を絞ったクラスとモジュール、そして一般的にはより多くの [〜#〜] solid [〜#〜] 、テスト可能なコードが得られます。
ユニットテストのないレガシーコードで作業し、手動で何かをテストする必要があるときはいつも、「このコードにユニットテストがすでにあると、はるかに速くなる」と考え続けます。結合度の高いコードに単体テスト機能を追加しようとするたびに、「分離された方法で記述されていれば、これはずっと簡単になる」と考え続けます。
TL; DR バージョン:
テストを作成するコストに加えて、必要な回数だけテストを実行するコストが、手動でテストするコストよりも少ない場合に、テストを作成しますする必要があります。
ただし、TDDを使用する場合、テストを作成するコストは、それが上手くなるにつれて低下する可能性が高く、コードが完全に自明でない限り、おそらく予想よりも頻繁にテストを実行することになります。
すぐにテストしてくださいリグレッションが発生するか、何かが引き起こされるのを恐れてください編集に気づかずに編集してください。
Kindleは恐れているので、十分なサイズに成長させましょう。テストが早くなるほど、良い結果が得られます。
ご注意ください:プロジェクトでの役割によっては、単体テストだけが作成したい種類のテストではない場合があります。
単体テストにだれもが夢中になっています。過去の主流のテスト慣行が悪かったためです。ただし、これまでにテストしたことがない場合は、テスト全般に集中する必要があります。単体テストだけでは世界の問題を解決できません。
「これを単体テストする必要がありますか」は、通常、次の質問に答えることで答えることができます。「この機能が適切に機能することは重要ですか、それが機能しなくなったときを知ることは重要ですか?」
もちろん、それよりもはるかに複雑ですが、それは開始するための良い方法です。最終的には、コードが別の関数で使用されているためにすでにテストされているかどうか、または時間を別の関数で費やすほうがよいかどうかなどについても検討します。
それはプロジェクトのサイズではなく、テストを使用するかどうかを決定するプロジェクトのタイプだと思います。
概念実証や、コーディングから学ぶことを目的とする他のプロジェクトに取り組んでいる場合は、テストは必要ありません。プロジェクトが使用されることを意図している場合、おそらく本番環境に送信されることさえあるのであれば、テストする必要があります。
Robert C. Martinの「クリーンコード」 からの引用:「書くのが簡単であれば、テストするのは簡単です」。
それは本当にサイズの問題ではありません-それはあなたがそれで何をするか(そしてそれが何歳か)です。テクノロジーがどのように機能するかを学び、物を捨てる計画を立てている場合(これをスクラムでのスパイクと呼びます)、多くのテストを行わずにコーディングするだけです。さらに開発を計画している場合は(たとえ単に手を出していても)、コードを中心にテストを作成する必要があります。 TDDは、テスト手法になる前から、設計手法です。実行の詳細に取り掛かる前に、コードで何をしたいかを明確に把握したいとします。また、[〜#〜]ではない[〜#〜]大量のレガシーコードを中心に広範なユニットテストを作成することをお勧めします。複雑な部分(サイクロマティックな複雑さ/スパゲッティコードの感覚が高い部分)と頻繁に失敗する部分(同じになることが多い)を特定してください。他の人が示唆しているように、私はTDDに関するケントベックの本を読みに行き、間違いなくマイケルフェザーの本を読みます。彼らがあまりカバーしていないのは、コードの周りでユニットテストを書くことの政治的の側面です。多くの開発者は、テスト可能にするためにコードを変更する必要がなく、コードをテストする必要性をまったく感じていません。それは私たちが職業として取り組む必要があるものです。他のすべてのエンジニアリング分野は、彼らの仕事が仕様を満たしていることを(しばしば数学的に)証明する必要があります。私たちは同じことをすべきです。