単体テストを行うには、プロジェクトの大きさはどれくらい必要ですか?[閉まっている]


86

私のプロジェクトは、単体テストを可能にするほど十分に分離されていると思います。しかし、単体テストを価値のあるものにするために、プロジェクトは、正確に、クラスと機能の面でどれだけ大きくする必要がありますか?

私たちは皆、間違いを犯し、完璧な人はいませんが、小さなプロジェクトのエラーをステップスルーで処理するための自分はまともなプログラマだと思います。または、プロジェクトのサイズに関係なく、単体テストは非常に必要ですか?


26
あなたがしている大きな誤った仮定は、プロジェクトはあなただけのためであり、それは今だけだということです。数か月間放置して、何か他のことをしてから戻ってきたらどうでしょうか?「まともなプログラマ」であることについて同じ自信を持っていますか(テストするかどうかとは関係ありません)。他の誰かがあなたのプロジェクトを引き継いだら...?偉大なブロガー(残念ながらもはやアクティブではありません)、常に「コードライターではなく、コードリーダーに対応する」べきだと書いています。
アモスM.カーペンター

6
これはどうですか(C#.NETの意味):int x = 3 *(1/3); 操作の完了後にxに保存される値は何ですか?私のポイントは、あなたが知らないか、間違っているコードを知っていたが間違っていたために、バグにつながる可能性があるため、1行のコードでさえテストが必要な場合があるということです。
NoChance

2
@aaamos、あなたは私のポイントを逃していると思います。私がこの質問を単独で聞かれるという事実は、コードリーダーへの対応も検討していることを示しています。
ラミンサンネ

13
両方の方法で行ったので、プロジェクトがarbitrary意的であると感じたときに戻って単体テストを書くよりも、進行中の(つまりプロジェクトが小さい間)テストを書く方がはるかに簡単です。今すぐテストを作成する必要があります」という条件です。
元気ウォンコ

1
あなたは間違った質問をしている。プロジェクトの大きさは関係ありません。問題は、それが正しい場合、どれだけ気にしますか?正確性が重要な場合、単体テストは正確性を改善する効果的な方法です。
マークE.ハーゼ

回答:


206

プロジェクトはすでに十分な大きさです。

私の経験では、単体テストの必要性を検討するには、1つのクラスと1つの関数で十分でした。

    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());
        }
    }

24
確かに、0クラス/ 0機能ポイントでより早く開始する必要があります... TDDをフォローしている場合:)
カズドラゴン

115
+1。プログラムがバグを抱えるのに十分な大きさであれば、単体テストを行うのに十分な大きさです。
ジェイソン

9
@JasonOrendorff:それをポスターにposter笑して、オフィスに置いています。ブリリアント。
ジャスティン

さらに、「安全な」リファクタリングが可能になります。
ティモ

7
感情に必ずしも同意するわけではありませんが、コードが本当に単純な場合は、本格的な単体テストの代わりにアサーションだけで逃げることができるでしょう。
チュウ

109

「すべてを単体テストする必要があります」というアイデアを購入したことはありませんが、確かにそこにいる人はいます(gnatの答えを参照してください!)。

私に関する限り、単体テストの主な利点は次のとおりです。

  1. 変更が物事を壊さないように支援する。
  2. クラスへの適切なインターフェイスの設計を支援します(独自のコードのクライアントになる必要があるため)。
  3. コードの使用方法を文書化するのに役立ちます。

基本的に、これらの要因に対するテストを作成および維持するのにかかる時間を検討する必要があります。

テスト1を書く価値があるようにするには、通常1で十分です。私の経験では、コードの95%以上が遅かれ早かれ変更されます。


8
これに同意します-単一の開発者ショップで作業する場合、ソフトウェアの品質とすべてのテスト(多くの時間がかかる可能性があります)のバランスを取る必要があります。変更を行うたびに、ユニットテストを修正する必要があるかもしれないことを忘れないでください
マットウィルコ

1
すべてをテストする必要はありませんが、外の世界にさらされている動作をテストする必要があります。確かにテストにはメンテナンスコストがかかり、Kent BeckがSOの答え(SOだったと思います)で述べたように、コードが正しいことを確信させるのに十分なテストを行います。
ウェインワーナー

10
最小限の自動化されたテストのみを実行している場合、単体テストはターゲットとするのに不適切なレベルであると付け加えます。代わりに、高レベルのインテグレーション/スモークテストを行い、いくつかのデータセットをアプリのエンドツーエンドでプッシュします。これらのテストで可能な限り多くのコードベースを実行し、すべての通常の使用例と実行パスをカバーする必要があります。75%の確率で、アプリのどこかで何かが壊れたことがわかると、5%の確率でSomeClass.OneOfTheHandfulOfTestedFunctions()が壊れたとわかるよりも有益です。
ダンニーリー

3
ええと、あなたは1つを見逃していると思います。「コードが想定どおりに機能することを確認する!」
BlueRaja-ダニーPflughoeft

3
@ BlueRaja-DannyPflughoeft:実際には、「コードが作成した単体テストに合格することを確認する!」と言う方が正確です。
vaughandroid

34

簡単です。一度実行した後にプログラムを破棄する場合、単体テストは必要ありません。

これが過度に思える場合は、代替案の意味を検討してください。単体テストで支払うことができないサイズがある場合、「まだ魔法のサイズに達しているのか、テストを書き始めるべきなのか」と判断し続ける必要があります。現在、プログラマは未来を予測することで悪名が高く、自分のスキルを判断することで悪名が高い。あなたにとって非常に明瞭に見えるコードは、たとえあなたにとっても、1か月も待たなければ理解できなくなります。あなたは絶対にしているプロジェクトは、積極的に特定が再び使用されることはありません、あなたは単にあなたが前に、何か解決方法をルックアップする場合がありますリモート機会に周り続けることだろう再度要求することを、変更要求を受信します。

したがって、テストが役立つかどうかを誤判断する可能性が非常に高く、テストが必要になった時点で、テストする正確なセマンティクスが実際に何であるかはすでに100%確実ではありません。些細な一回限りのプログラムを除くすべてが単体テストから利益を得ると信じているため、二度と実行されないテストに費やす労力のコストは、テストされておらず理解されていないコードを拡張するリスクに対して無視できると考えています。


22
プログラマは、将来を予測する、自分のスキルを判断で悪名高い悪いです
superM

3
@superM私はあなたに同意します。私の短いキャリアの間にすでに書いた「一度実行して捨てる」プログラムはすべて残り、数日ごとに実行され、ビジネスクリティカルになりました。私は、「一時的な」別名一時的な永続的な効果と呼びます。...ため息
ジャレイン

@Jalayn答えは、この実現が達成されたらすぐに戻って単体テストを追加する必要があるというだけではありませんか?
コーネルマッソン

あなたは絶対的に正しい@CornelMasson、それはテストが:-)欠けているので、「それはまだ終わっていない」ことを経営者を説得することはしばしば困難だということを期待
Jalayn

@Jalayn:本当だ!
コーネルマッソン

22

しばらく前、私は素晴らしい記事を見つけました:ユニットテストが開発を高速化する理由。質問に答えるのに役立ちます。

...コードベース...に相当な単体テストが提供された場合 「すべてのテストが成功した場合、コードが実行すべきことを保証します」と言うセットであり、テストが失敗した場合、動作がどこで壊れているかを正確に示します。これは素晴らしいことです。コードがまだすべきことを実行しているなら、迷わずに必要なものを追加するようにコードを変更できます。これはソフトウェアエンジニアとしての素晴らしい世界です。もっと速く進むことができることに気づいた...

私には「信仰」があります。

これはおそらく、単体テストがエンタープライズコンテキストでの開発を高速化する最も重要な理由です。

すべてのテストに合格すれば、すべてが正常に機能することを信頼できます。テストが失敗した場合、問題が発生した場所を正確に指摘します...

... 高いユニットテストカバレッジ優れたユニットテストが必要です。これらの条件が順守されると、新しい機能を追加するための努力がアプリケーションのサイズにほとんど依存せず、長期的には開発がスピードアップするという状況に陥ります。

Michael Feathersは、彼の著書の1つで、コードの変更を扱う2つの方法を紹介しました。

  • 編集と祈り、
  • カバーして変更します。

コードベースの大きさは関係ありません。


18

Kent BeckによるStack Overflowの質問への回答によると、ユニットテストはどのくらい深くなっていますか?、間違っている傾向があるコードをテストする必要があります。

コンストラクターで間違った変数を設定するなど、通常、ある種の間違いをしない場合は、テストしません。


4
良い点であり、これはOPの質問が間違っていることを意味します。テストするかどうかは、プロジェクトのサイズとは関係ありません。5行のコードベースではテストが必要な場合があり、大規模なコードベースの1行のメソッドでは必要ない場合があります(ただし、そのコードベース内の他のものは必要です)。
ネイサンロング

これは、あなたが一人で取り組んでいる小さなプロジェクトではうまくいくかもしれませんが、仕事のために行われるプロジェクト(将来誰がそれを扱うかを制御しない場合)またはオープンソースであるかもしれない何かのために、あなたは必要ですすべてをテストします。後で「開始済みのすべてのコードをバックフィルするのが難しい」ため、すぐに開始する必要があります
-xaxxon

@xaxxon:Kentは実際にMansuroがリンクしたのと同じ答えでそれについて語っています:「チームでコーディングするとき、私は戦略を修正して、集合的に間違っている傾向があるコードを慎重にテストします。」
ヘンコ

いいえ、それはまだ信じられないほど短い目です。誰が将来コードを開発するのかはわかりません。これは、ジュニア開発者を苦しめるタイプの考え方です。
xaxxon

5

ユニットテストは、時間を節約して改善するために実装されています。

  • バグ追跡
  • コードのリファクタリングおよび/または書き換え
  • 統合テスト
  • 回帰テストなど

プログラムの比較的複雑な部分の単体テストを作成する必要があります。

単体テストを今書いても将来の時間を節約できないと確信している場合は、スキップできます。しかし、あなたは決して知らず、個人的には、ユニットテストを書くのではなく、手動ですべてのテストを行うほうが(時間、お金、神経の面で)安い場合を考えることはできません。


一般的に良い答えなので、+ 1。ただし、あなたの最後のポイントは、ユニットテストを手動でテストする必要があるという事実を見逃していると思います。
vaughandroid

@Baquetaは、多分私はクリアな音しませんでしたが、私はそのユニットテストは完全に手動テストを置き換えると言う意味ではありませんでした
superM

4

「これを単体テストする必要があります」は、通常、次の質問に答えることで答えることができます。「この機能が適切に機能することは重要ですか。

もちろん、それはそれよりもはるかに複雑ですが、それは開始するための良い方法です。最終的には、別の関数で使用されているためにコードが既にテストされているかどうか、または別の関数で時間を費やす方がよいかどうかなども考慮します。


4

テストせずにコードを記述する場合を除き、常にテストのコストが発生します。

単体テストを使用する場合と使用しない場合の違いは、テストを記述するコストと実行するコストを手動でテストするコストと比較した場合の違いです。

単体テストの作成コストが2分で、単体テストの実行コストが実質的に0であるが、コードの手動テストのコストが1分である場合、テストを2回実行した場合でも中断します。


長年、私は自分のコードの単体テストを書くのに十分な時間がないという誤解を受けていました。私がテストを書いたとき、それらは肥大化した、重いものであり、それが必要だとわかったときにのみユニットテストを書くべきだと考えるように促しました。

最近、テスト駆動開発を使用するように勧められましたが、完全な啓示であることがわかりました。私は今、ユニットテストを書かない時間がないと確信しています

私の経験では、テストを念頭に置いて開発することで、よりクリーンなインターフェース、より焦点を絞ったクラスとモジュール、そして一般的にテスト可能なコードがよりソリッドになります。

ユニットテストのないレガシーコードを使用し、手動で何かをテストする必要があるたびに、「このコードにすでにユニットテストが含まれていると、これはずっと速くなる」と考え続けます。結合テストの高いコードに単体テスト機能を追加しようとするたびに、「分離された方法で記述されていれば、これは非常に簡単になる」と考え続けます。


TL; DRバージョン:

テストを記述するコストと、必要な回数だけ実行するコストが、必要な回数だけ手動でテストするコストよりも低い可能性が高い場合は、テストを記述します。

ただし、TDDを使用する場合は、テストを作成するコストが上達するにつれて低下する可能性が高く、コードがまったく些細でない限り、予想よりも頻繁にテストを実行することになります。


3

リグレッションが発生するの確認したらすぐにテストするか、編集に何らかの原因で気付かないことを恐れます。

恐れるKindleは、適切なサイズに成長させてください。テストを早めるほど良いでしょう。

注:プロジェクトでの役割によっては、単体テストだけで作成したいテストではない場合があります。

過去の主流のテスト慣行が悪いため、誰もがユニットテストに取りつかれています。しかし、以前にテストしたことがない場合は、一般テストに集中する必要があります。単体テストだけでは世界の問題を解決することはできません。


1
あなたが指摘しているように見えますが、スタートアッププログラマーの基本的な出発点を単体テストしているわけではありません。また、「一般的なテスト」の意味について詳しく説明していただけますか。ありがとう。
ラミンサンネ

1
他に少なくとも2つのタイプのテストがあります-統合テストと受け入れテスト。単体テストは特定のユニットを対象としています(たとえば、このクラスのこの関数はFizz the Fizzを想定しています)。そのクラスが相互作用する他のすべての場所をモック/スタブし、fake-oデータを渡します。統合テストを行うときは、2つ(またはそれ以上)のクラスを組み合わせて、クラスが想定どおりに連携するようにします。最終的に、システム全体のエンドツーエンドのテストを行うのに十分なテストを構築します。これは「スモークテスト」とも呼ばれます。
ウェインワーナー

回帰テストの宣伝文句もあります。回帰テストは通常​​、単体テストよりも大きく、構築に1日かかる場合があり、テストデータおよび特別なテスト環境へのアクセスを意味する場合があります。実際、単体テストは(旧式の)回帰テストのより小さく、より洗練された、保守しやすいバージョンです。
ZJR

1

私は、プロジェクトのサイズではなく、テストを使用すべきかどうかを決定するプロジェクトのタイプだと考えています。

概念実証に取り組んでいる場合、またはコーディングから学習することが目標である他のプロジェクトに取り組んでいる場合、テストは必要ありません。プロジェクトを使用することを目的としている場合、場合によっては実稼働環境に送信する場合でも、テストする必要があります。

Robert C. Martinの "Clean Code"からの引用: "書くのが簡単なら、テストするのは簡単だ"ので、短くてつまらないプログラムのテストをスキップする言い訳はありません。


0

それは本当にサイズの問題ではありません-それはあなたがそれで何をするかです(そしてそれは何歳ですか)。テクノロジーがどのように機能するかを学び、それを捨てることを計画している場合(これをスクラムのスパイクと呼びます)、多くのテストを行わずにコーディングします。さらに開発することを計画している場合(ただうんざりしている場合でも)、コードの周りにテストを書く必要があります。TDDは、テスト手法になる前の設計手法です。実行の詳細に縛られる前に、コードに何をさせたいかを明確に把握しておく必要があります。私もしないだろう大量のレガシーコードに関する広範なユニットテストを作成することをお勧めします。複雑な部分(サイクロマティックの複雑さ/スパゲッティコードの感覚が高い部分)と頻繁に失敗する部分(多くの場合同じもの)を特定するようにしてください。他の人が示唆しているように、私はTDDに関するケント・ベックの本を読み、間違いなくマイケル・フェザーの本を読みました。彼らがあまりカバーしていないのは、コードに関するユニットテストを書くことの政治的側面です。多くの開発者はコードをテスト可能にするためにコードを変更する必要がないことを嫌い、多くの開発者はコードをまったくテストする必要性を感じていません。それは私たちが職業として取り組むべきものです。他のすべてのエンジニアリング分野は、彼らの仕事が仕様を満たしていることを(多くの場合数学的に)証明する必要があります。同じことをする必要があります。


-1

クラスまたは機能の制限でプロジェクトをバインドし、ユニットテストに適しているかどうかを判断するのは間違っている可能性があります。アプリケーションの単体テストには多くの利点がありますが、アプリケーションを維持したり、分散環境で作業したりする必要があるときに、本当の美しさが始まります。そのため、ここで選択します。コードの小さな変更でさえ、災害を引き起こす可能性があります。
「ユニットテスト」を推奨するだけでなく、コードカバレッジを確認して、コードの最大値がユニットテストでカバーされるようにすることもお勧めします。コードカバレッジのしきい値は95%を下回ってはならず、目標は約100%でなければなりません。コードカバレッジを追跡し、レポートを生成するツールを利用できます。
Visual Studioはカバレッジデータを提供します-http://msdn.microsoft.com/en-us/library/ms182496(v=vs.80).aspx
また、NCoverまたはdotCoverを使用できます。

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