ユニットテストが多すぎるということはありますか?


139

私は、既存のアプリケーションの単体テストの作成を任されています。最初のファイルを完成させた後、元のコードの419行に対して717行のテストコードがあります。

コードカバレッジを増やすと、この比率は管理不能になりますか?

単体テストの私の理解は、クラス内の各メソッドをテストして、すべてのメソッドが期待どおりに機能することを確認することでした。しかし、プルリクエストで、技術リーダーは、より高いレベルのテストに焦点を当てる必要があると指摘しました。彼は、各機能を徹底的にテストするのではなく、問題のクラスで最も一般的に使用される4〜5つのユースケースをテストすることを提案しました。

技術リーダーのコメントを信頼しています。彼は私よりも多くの経験があり、ソフトウェアの設計に関しては本能が優れています。しかし、このような曖昧な標準のテストを複数のチームがどのように書くのでしょうか。つまり、どのようにして仲間を知り、「最も一般的なユースケース」について同じ考えを共有しますか?

私にとって、100%の単体テストのカバー率は高い目標ですが、50%にしか達していない場合でも、その50%の100%がカバーされていることがわかります。それ以外の場合、各ファイルの一部のテストを作成すると、多くのチートの余地が残ります。


145
場合によります。三目並べのゲームを書いていますか、それとも原子炉を管理するコードを書いていますか?
ブライアンオークリー

11
十分な数の単体テストを使用すると、Pentium FDIVバグや暗号プリミティブの相関関係など、エキゾチックなハードウェア実装の問題を検出できます。したがって、過去の単体テストが役に立たない厳しい制限はないようです。コストがかかりすぎる場合の実用的な制限です。
ナット

5
より高いレベルでテストすることで、実際のカバレッジの見通しがよくなります。実際のカバレッジとは、システムの通常の使用中に発生する可能性が高いことを意味します。それはあなたが最初に達成したい種類の報道です。到達する最後の50%には、YAGNIまたはデッドコードが含まれている可能性がありますが、これらのコードは削除されると、全体的なカバレッジも増加します。
ライヴ

5
あまりにも多くのテストを取得している場合(現時点ではテストしていないようです)、最も可能性の高い問題は、テストしているコードの実行が多すぎることです。したがって、単一の責任は遵守されません。コードが適切に分割されている場合、テストでも大きな負担は生じません。クラスが多くのことをしたり、副作用などがたくさんあると、悪夢になります。
リュックフランケン

12
sqliteのテストドキュメントは、sqlite.org / testing.htmlという楽しい読み物です。引用:「SQLiteライブラリは約122.9 KSLOCのCコードで構成されています。比較すると、プロジェクトには745倍のテストコードとテストスクリプトがあります-91596.1 KSLOC」。
user60561

回答:


180

はい、100%のカバー率で、必要のないテストを作成します。残念ながら、どのテストが不要かを判断する唯一の信頼できる方法は、すべてのテストを書き、10年ほど待って、どのテストが失敗しないかを確認することです。

通常、多くのテストを維持することは問題ありません。多くのチームは、100%の単体テストの範囲に加えて、自動化された統合およびシステムテストを実施しています。

ただし、テストメンテナンスフェーズではなく、追いついています。クラスの50%をテストカバレッジ100%にするよりも、クラスの100%をテストカバレッジ50%にする方がはるかに優れており、リードがそれに応じて時間を割り当てようとしているようです。そのベースラインを取得したら、次のステップは通常、今後変更されるファイルを100%プッシュすることです。


11
ご回答有難うございます。それは私の質問を視野に入れ、本当の問題、私の態度に対処するのに役立ちました!+1
user2954463

43
@astraあなたの態度はそれほど悪くはありません。理由を質問するのは良いことです。あなたのその他の質問に答えるために、「私の仲間を知り、「最も一般的なユースケース」について同じ考えを共有しますか?あなたは彼らにあなたのテストを見てもらいます。彼らのテストを見てください。コードレビューテストは時間の無駄ではありませんが、私は会議室ではなくターミナルで作業する傾向があります
-candied_orange

18
テスト10年間で失敗したことがないことも、それが不要であることを保証するものではありません、それは年11で失敗に終わる可能性
Pharap

24
実際には、反対のアプローチを取ることができます。一般的なケースをカバーすると思われるテストを作成します。ただし、障害が発生するたびに、その領域をカバーするテストを作成してください。
スタニウス

10
@Pharapこの答えに関する私の唯一の問題は、テストが失敗した場合にのみ値を追加できるという暗黙の仮定があるということです。また、優れた単体テストは、優れた形式のドキュメントを提供します。また、テストの作成時に、再利用性/構成可能性/カプセル化について考えるように強制することで、価値を追加しました。私の経験でテストされていないコードは、柔軟性のないモノリシックな獣である傾向があります。
-ArT

66

テスト駆動開発を使用して作成された大規模なコードベースで作業したことがある場合は、ユニットテストが多すぎるなどの問題が発生する可能性があることを既にご存じでしょう。場合によっては、開発作業の大部分は、実行時に関連クラスの不変式、前提条件、および事後条件のチェックとして実装される低品質のテストの更新で構成されます(つまり、より高いレベルのテストの副作用としてのテスト)。

別の問題は、貨物カルト駆動の設計手法を使用した低品質の設計の作成であり、テスト対象(クラス、インターフェイスなど)が急増します。この場合、テストコードの更新が負担のように見えますが、本当の問題はデザインの質の低さです。


16
前提条件、事後条件、および不変式を指摘することに賛成する場合は、単体テストとして扱う必要があります。そのように、そのデバッグコードがアクティブな場合、すべての使用は単体テストになります。
Persixty

これは素晴らしい答えであり、私の経験と完全に一致しています。
トニー・エニス

そしてもう1つの問題:大量の低品質を備えたゲートチェックイン(本当に必要です!)がある場合、テストを長時間実行しても、実際のメリットが得られずにすべてが遅くなります。そして、クラスの1つの項目を変更し、何百ものテストが失敗するという楽しい事実は明らかです。
VOO

3
これは受け入れられているものよりもはるかに良い答えです!「場合によっては、開発作業の大部分が低品質のテストの更新で構成されています」-私はこれを経験しましたが、それはひどいものです。いくつかの点で、テストがまったくないこと以上のもの。
ベンジャミンホジソン

36

質問への回答

ユニットテストが多すぎるということはありますか?

確かに...たとえば、一見異なるように見えるが、実際には同じことをテストする複数のテストを行うことができます(論理的には、テスト対象の「興味深い」アプリケーションコードの同じ行に依存します)。

あるいは、決して外に出ないコードの内部をテストすることもできます(つまり、いかなる種類のインターフェイスコントラクトの一部でもありません)、それが理にかなっているかどうかについて議論することができます。たとえば、内部ログメッセージの正確な表現など。

私は、既存のアプリケーションの単体テストの作成を任されています。最初のファイルを完成させた後、元のコードの419行に対して717行のテストコードがあります。

それは非常に普通のように私を打つ。テストでは、実際のテストに加えて、セットアップと解体に多くのコード行を費やします。比率は改善される場合と改善されない場合があります。私自身は非常に重いテストであり、実際のコードよりも多くの場所と時間をテストに費やしています。

コードカバレッジを増やすと、この比率は管理不能になりますか?

比率はあまり考慮しません。テストを管理不能にする傾向がある他のテストの品質があります。コードをかなり単純に変更するときに、一連のテスト全体を定期的にリファクタリングする必要がある場合は、理由をよく調べる必要があります。そして、それらはあなたが持っている行の数ではなく、テストのコーディングにどのようにアプローチするかです。

単体テストの私の理解は、クラス内の各メソッドをテストして、すべてのメソッドが期待どおりに機能することを確認することでした。

これは厳密な意味での「ユニット」テストに適しています。ここで、「ユニット」はメソッドやクラスのようなものです。「ユニット」テストのポイントは、システム全体ではなく、1つの特定のコードユニットのみをテストすることです。理想的には、システムの残りすべてを削除します(doubleまたはその他を使用)。

しかし、プルリクエストで、技術リーダーは、より高いレベルのテストに焦点を当てる必要があると指摘しました。

それから、あなたは、人々がユニットテストと言ったときに、実際にユニットテストを意味していると仮定するというtrapに陥りました。「ユニットテスト」と言うが、まったく違うことを意味する多くのプログラマに会ったことがあります。

彼は、各機能を徹底的にテストするのではなく、問題のクラスで最も一般的に使用される4〜5つのユースケースをテストすることを提案しました。

確かに、重要なコードの上位80%に集中するだけで、負荷も軽減されます。上司を高く評価していることを感謝していますが、これは私にとって最適な選択ではありません。

私にとって、100%の単体テストのカバー率は高い目標ですが、50%にしか達していない場合でも、その50%の100%がカバーされていることがわかります。

「ユニットテストカバレッジ」とは何なのかわかりません。「コードカバレッジ」、つまり、テストスイートの実行後、コードのすべての行(= 100%)が少なくとも1回実行されたことを意味すると仮定します。

これは素晴らしい球場指標ですが、撮影できる最高の標準ではありません。コード行を実行するだけでは全体像ではありません。これは、たとえば、複雑なネストされたブランチを通るさまざまなパスを考慮していません。これは、テストが少なすぎるコードの断片を指し示す指標のようなものです(明らかに、クラスが10%または5%のコードカバレッジである場合、何かが間違っています)。一方、100%のカバレッジでは、十分なテストを行ったかどうか、または正しくテストしたかどうかはわかりません。

統合テスト

人は常に話しているときには、実質的に私を悩ますユニットのデフォルトでは、今日のテスト。私の意見(経験)では、ユニットテストは、ライブラリ/ APIのための素晴らしいです。よりビジネス志向の領域(手元の質問のようなユースケースについて話す場所)では、必ずしも最良の選択肢ではありません。

一般的なアプリケーションコードおよび平均的なビジネス(お金を稼ぐ、納期を守る、顧客満足度を満たすことが重要であり、主にユーザーの顔に直接あるバグ、または実際の災害につながる可能性のあるバグを回避する場合) NASAロケットの打ち上げについてはこちらをご覧ください)、統合テストまたは機能テストははるかに便利です。

これらは、行動駆動型開発または機能駆動型開発と密接に関係しています。定義上、これらは(厳密な)単体テストでは機能しません。

短くするために、統合/機能テストはアプリケーションスタック全体を実行します。Webベースのアプリケーションでは、それはアプリケーションを介してクリックするブラウザのように作用するであろう(となし、明らかにそれはありません持っているという単純なことを、非常に強力なフレームワークは、それを行うためにそこにある-チェックアウトにhttp://キュウリ。例としてio)。

ああ、最後の質問に答えるには、機能テストが実装されて失敗した後にのみ新しい機能がプログラムされるようにすることで、チーム全体に高いテスト範囲を提供します。はい、それはすべての機能を意味します。これにより、100%(ポジティブ)の機能カバレッジが保証されます。定義上、アプリケーションの機能が「なくなる」ことはありません。100%のコードカバレッジを保証するものではありません(たとえば、ネガティブな機能を積極的にプログラミングしない限り、エラー処理/例外処理を実行することはありません)。

バグのないアプリケーションを保証するものではありません。もちろん、明らかにまたは非常に危険なバグのある状況、間違ったユーザー入力、ハッキング(たとえば、周辺のセッション管理、セキュリティなど)のための機能テストを作成する必要があります。しかし、ポジティブなテストをプログラミングするだけでも大きな利点があり、最新の強力なフレームワークでかなり実現可能です。

機能/統合テストには明らかに独自のワームがあります(たとえば、パフォーマンス、サードパーティのフレームワークの冗長テスト、通常はダブルを使用しないので、私の経験では書くのが難しい傾向があります...) d毎日、100%コードカバレッジユニットテスト済みアプリケーション(ライブラリーではありません!)よりも100%ポジティブ機能テスト済みのアプリケーションを使用します。


1
統合テストは優れていますが、単体テストに代わるものではなく、ビジネスアプリケーションにも代わるものではありません。それらには複数の問題があります:a)定義上、実行に時間がかかります(増分テストはほとんど役に立たないことも意味します)、b)実際の問題を特定するのが非常に難しくなります(oh 50統合テストが失敗しました、どのような変更が原因ですか?)およびc)同じコードパスを繰り返しカバーしています。
Voo

1
a)ゲーテッドチェックインでのテストの実行が面倒であり、プログラマが開発中にテストを繰り返し実行する可能性が低くなるため、問題です。これは、b)効率とバグを迅速に診断する能力を低下させます。c)1つの小さなことを変更すると、数十または数百(そこにある)の統合テストが簡単に失敗する可能性があることを意味します。また、これらのテストを記述するのは面倒または不可能であるため、統合テストのほとんどは幸せなパスのみをテストします。
Voo

1
@Voo、あなたが書いたものはすべて真実であり、私が知る限り、あなたが答えで指摘したすべての問題をすでに述べた
...-AnoE

あなたがその要約に同意する場合、ユニットテストよりも統合テストを好むという結論にどのように到達できるのか、私には本当にわかりません。大規模なプログラムの包括的な統合テストスイートは、実行するのに数時間から数日かかることもありますが、実際の開発ではほとんど役に立ちません。そして、受け入れテスト(誰もが行っていることですよね?)は、統合テストが単体テストで見逃してしまうのと同じ問題の多くをキャッチします-しかし、逆は真実ではありません。
Voo

24

はい、ユニットテストが多すぎる可能性があります。たとえば、単体テストで100%のカバレッジがあり、統合テストがない場合、明らかな問題があります。

いくつかのシナリオ:

  1. テストを特定の実装に過剰設計します。次に、実装を変更するときではなく、リファクタリング時に単体テストを破棄する必要があります(パフォーマンスの最適化を実行する際の非常に頻繁な問題点)。

    単体テストと統合テストの適切なバランスにより、重要なカバレッジを失うことなくこの問題を軽減できます。

  2. テストの20%ですべてのコミットを適切にカバーし、残りの80%を統合または少なくとも別個のテストパスに残します。このシナリオで見られる主な悪影響は、テストの実行に長い時間待たなければならないため、ゆっくりとした変化です。

  3. コードを修正しすぎて、テストできません。たとえば、変更が不要なコンポーネントや、少なくともそれらを一般化することはコストがかかり、優先度が低いコンポーネントでのIoCの悪用が多く見られましたが、人々はユニットテストを許可するために多くの時間をかけて一般化およびリファクタリングします。

私は、ファイルの50%を100%でカバーするのではなく、ファイルの100%を50%でカバーするという提案に特に同意します。最も一般的なポジティブなケースと最も危険なネガティブなケースに最初の努力を集中してください。エラー処理と異常なパスにあまり投資しないでください。重要ではないからではなく、限られた時間と無限のテスト領域があるからです。そのため、どの場合でも優先順位を付ける必要があります。


2
これは単体テストの問題ではありませんが、他のレベルで適切なテストを作成して実行するためのリソースを費やすことなく、単体テストのカバレッジに特定の数を要求することで優先順位を間違えている組織にとっては問題です。
ジュウェンティング

2
#3に強く同意し、低レベルクラスのインスタンスを高レベルクラスに手動で渡すことにも拡張します。高レベルのものが何かを達成するために低レベルのものに依存している場合、それは大丈夫です。それが発信者からそれの詳細を隠しているなら、私はその良いデザインと呼ぶでしょう。しかし、高レベルのもののインターフェースの一部を低レベルのものにし、テストをきれいにするために呼び出し元にそれを渡すようにすると、今では尻尾が犬を振っている。(低レベルのものが多くの場所で再利用され、大きく変化すると、それは物事を変化させます。私の経験では典型的ではありませんでした。)
johncip

私は間違いなくそれは素敵なクラスがコンストラクタに不必要な必須パラメータの束を追加することにより、恐ろしい取得する方法の頻繁な例は...ある、あなたの説明の@johncipを愛する
ブルーノ・ガーディア

19

各テストには費用と利点があります。欠点は次のとおりです。

  • テストを作成する必要があります。
  • テストの実行には(通常、非常に短い)時間がかかります。
  • テストはコードで維持する必要があります-テストするAPIが変更されると、テストも変更する必要があります。
  • テストを記述するために設計を変更する必要がある場合があります(ただし、これらの変更は通常は改善のためです)。

費用が便益を上回る場合、テストは書かずに行うほうが良いでしょう。たとえば、機能をテストするのが難しく、APIが頻繁に変更され、正確さが比較的重要でなく、テストで欠陥が見つかる可能性が低い場合は、おそらく記述しない方が良いでしょう。

テストのコードに対する特定の比率については、コードのロジック密度が十分であれば、その比率を保証できます。ただし、一般的なアプリケーション全体でこのような高い比率を維持する価値はおそらくないでしょう。


12

はい、ユニットテストが多すぎるなどのことがあります。

テストは良好ですが、すべてのユニットテストは次のとおりです。

  • APIと密接に結びついている潜在的なメンテナンスの負担

  • 他のことに費やすことができる時間

  • 単体テストスイートの時間のスライス
  • 実際には他のテストの複製であり、他のテストが成功し、このテストが失敗する可能性が非常に低いため、実際の値を追加しない場合があります。

100%のコードカバレッジを目指すのが賢明ですが、それは特定のエントリポイント(関数/メソッド/呼び出しなど)でそれぞれが100%のコードカバレッジを個別に提供する一連のテストを意味します。

良いカバレッジを達成してバグを追い出すのがどれほど難しいかを考えれば、真実はおそらく「ユニットテストが多すぎる」だけでなく「ユニットテストが間違っている」というようなものがあるということでしょう。

ほとんどのコードの語用論は以下を示します。

  1. エントリポイントを100%網羅し(すべてが何らかの形でテストされます)、「エラーのない」パスを100%近いコードカバレッジにすることを目指します。

  2. 関連する最小/最大値またはサイズをテストします

  3. 面白い特別なケース、特に「奇数」値と思われるものをすべてテストします。

  4. バグを見つけたら、そのバグを明らかにする単体テストを追加し、同様のケースを追加する必要があるかどうかを考えます。

より複雑なアルゴリズムについては、以下も考慮してください。

  1. より多くのケースのいくつかの一括テストを行います。
  2. 結果を「ブルートフォース」実装と比較し、不変条件をチェックします。
  3. ランダムテストケースを作成し、不変条件を含むブルートフォースおよび事後条件をチェックする方法を使用します。

たとえば、ランダム化された入力を使用して並べ替えアルゴリズムをチェックし、データをスキャンして最後に並べ替えることを検証します。

あなたの技術リーダーは、「最小限の裸のお尻」テストを提案していると思います。「最高価値の品質テスト」を提供していますが、その間にはさまざまなものがあります。

たぶんあなたの先輩は、あなたが構築しているコンポーネントがより大きな部分に埋め込まれ、統合されたときにより徹底的にユニットテストされることを知っているかもしれません。

重要な教訓は、バグが見つかったときにテストを追加することです。ユニットテストの開発に関する私の最高の教訓を導きます:

サブユニットではなくユニットに注目してください。サブユニットからユニットを構築する場合、サブユニットがもっともらしいと思われるまで非常に基本的なテストを記述し、制御ユニットを介してサブユニットをテストすることでより良いカバレッジを達成します。

そのため、コンパイラを作成していて、シンボルテーブルを作成する必要がある場合(たとえば)。基本的なテストでシンボルテーブルを取得して実行し、テーブルを埋める宣言パーサーで(たとえば)作業します。バグが見つかった場合にのみ、シンボルテーブルの「スタンドアロン」ユニットにテストを追加してください。それ以外の場合は、宣言パーサーと後でコンパイラー全体の単体テストによるカバレッジを増やします。

これは最高の価値をもたらします(全体の1つのテストは複数のコンポーネントをテストします)。より安定する傾向のあるテストでは「外部」インターフェイスのみが使用されるため、再設計と改良の能力が残ります。

デバッグコードテストの事前条件、すべてのレベルの不変条件を含む事後条件と組み合わせることで、最小限のテスト実装から最大限のテストカバレッジを得ることができます。


4
100%のカバー率が実用的であるとは言いません。100%のカバレッジは非常に高い水準です。
ブライアンオークリー

残念ながら、ランダム化された方法でもエラーを見逃す可能性があります。非公式であっても、証明に代わるものはありません。
フランクヒルマン

@BryanOakleyポイントを取った。それは誇張です。しかし、人々が信用を与えるよりもそれに近づくことが重要です。「私はそれがすべて良い簡単なパスをテストしました」は、常に問題を引き起こすでしょう。
Persixty

@FrankHileman質問は、「ソフトウェアを慎重に設計し、静的チェックロジックを実行し、アルゴリズムを証明するのに代わるユニットテストである」ではなく、答えは「いいえ」です。どちらの方法でも、高品質のソフトウェアを独自に作成することはできません。
Persixty

3

まず、本番コードよりも多くのテストを用意することは必ずしも問題ではありません。テストコードは線形であり、理解するのが簡単です-必要な複雑さは、実稼働コードであるかどうかに関係なく、非常に低いです。テストの複雑さが実稼働コードの複雑さに近づき始めた場合、問題がある可能性があります。

はい、単体テストが多すぎる可能性があります-単純な思考実験により、追加の価値を提供しないテストを追加し続けることができ、追加されたすべてのテストが少なくとも一部のリファクタリングを禁止できることがわかります。

私の意見では、最も一般的なケースのみをテストするというアドバイスには欠陥があります。これらはシステムテストの時間を節約するためのスモークテストとして機能するかもしれませんが、本当に価値のあるテストはシステム全体で実行するのが難しいケースをキャッチします。たとえば、メモリ割り当てエラーの制御されたエラー注入を使用して、完全に未知の品質の回復パスを実行できます。または、除数(または平方根となる負の数)として使用されることがわかっている値としてゼロを渡し、未処理の例外が発生しないようにします。

次に重要なテストは、極限または境界点を実行するテストです。たとえば、年の(1から始まる)月を受け入れる関数は、0、1、12、および13でテストする必要があるため、有効な無効な遷移が正しい場所にあることがわかります。これらのテストにも2..11を使用するのはオーバーテストです。

既存のコードのテストを作成する必要があるという点で、あなたは難しい立場にいます。コードを記述している(または記述しようとしている)ときに、エッジケースを特定するのは簡単です。


3

単体テストの私の理解は、クラス内の各メソッドをテストして、すべてのメソッドが期待どおりに機能することを確認することでした。

この理解は間違っています。

ユニットテストは、検証動作テスト中のユニットを

その意味で、ユニットは必ずしも「クラス内のメソッド」ではありません。The Unit of Unit Testingの Roy Osheroveによるユニットの定義が好きです:

ユニットとは、同じ理由で変更されるすべての製品コードです。

これに基づいて、単体テストはコードのすべての望ましい動作を検証する必要があります。「欲求」が多かれ少なかれ要件から取られる場合。


しかし、プルリクエストで、技術リーダーは、より高いレベルのテストに焦点を当てる必要があると指摘しました。

彼は正しいが、彼が考えるとは異なる方法で。

あなたの質問から、私はあなたがそのプロジェクトの「専用テスター」であることを理解しています。

大きな誤解は、あなたがユニットテストを書くことを期待しているということです(「ユニットテストフレームワークを使用したテスト」とは対照的です)。Ynitテストの作成は、テスターではなく開発者の責任です(理想的な世界では...)。一方、この質問にTDDをタグ付けしました。これはまさにこれを意味します。

テスターとしてのあなたの仕事は、モジュールやアプリケーションのテストを書く(または手動で実行する)ことです。そして、この種のテストでは、主にすべてのユニットがスムーズに連携することを確認する必要があります。つまり、各ユニットが少なくとも1回実行されるようにテストケースを選択する必要があります。そして、そのチェックは実行されます。実際の結果は、将来の要件によって変更される可能性があるため、それほど重要ではありません。

ダンプ自動車の例えをもう一度強調するには:組立ラインの最後で、自動車で何回テストを行いますか?正確に1つ:それ自体で駐車場にドライブする必要があります...

ここでのポイントは次のとおりです。

「単体テスト」と「単体テストフレームワークを使用して自動化されたテスト」の違いを認識する必要があります。


私にとって、100%の単体テストのカバー率は高い目標ですが、50%にしか達していない場合でも、その50%の100%がカバーされていることがわかります。

単体テストは安全策です。既に実装されている動作を壊すことを恐れることなく、技術的な負債を減らしたり、新しい動作を追加したりするために、コードをリファクタリングする自信を与えます。

100%のコードカバレッジは必要ありません。

ただし、100%の動作カバレッジが必要です。(はい、コードカバレッジと動作カバレッジは何らかの形で相関していますが、そのため同一ではありません。)

動作範囲が100%未満の場合、テストスイートの実行が成功しても、テストされていない動作の一部を変更できたため、何も意味がありません。そして、リリースがオンラインになった翌日にクライアントに気付かれます...


結論

テストなしよりも優れたテストはほとんどありません。間違いない!

しかし、ユニットテストが多すぎるようなものはありません。

これは、各ユニットテストがコードの動作に関する単一の期待を検証するためです。また、コードに期待する以上の単体テストを書くことはできません。また、安全ハーネスに穴が開いていると、生産システムに有害な変更が加えられる可能性があります。


2

もちろん。私は以前、大規模なソフトウェア会社のSDETでした。私たちの小さなチームは、以前ははるかに大きなチームで処理されていたテストコードを維持する必要がありました。それに加えて、製品にはいくつかの依存関係があり、それが絶えず重大な変更を導入していました。つまり、継続的なテストメンテナンスを意味します。チームの規模を拡大するオプションはなかったため、失敗した場合は価値の低いテストを何千も捨てなければなりませんでした。そうしないと、欠陥に追いつくことができなくなります。

これを単なる管理上の問題として却下する前に、現実世界の多くのプロジェクトがレガシーステータスに近づくにつれて人員の削減に苦しむことを考慮してください。場合によっては、最初のリリースの直後に発生することもあります。


4
「それに加えて、当社の製品にはいくつかの依存関係があり、それが絶えず重大な変更を導入していました。つまり、継続的なテストメンテナンスを意味します。」-あなたの言うテストは、依存関係が絶えず壊れている場合、貴重なテストのようなメンテナンス音が必要です。
CodeMonkey

2
それはテストの問題ではなく、組織の問題です。
ジュウェンティング

2
@CodeMonkey依存関係は壊れていません。これらは、製品の変更を必要とする方法で更新されていました。はい、テストは価値がありましたが、他のテストほど価値はありませんでした。自動テストは、同等の手動テストが難しい場合に最も価値があります。
-mrog

2
@jwentingはい、それは組織の問題であり、コードの問題ではありません。ただし、テストが多すぎるという事実は変わりません。調査できない失敗したテストは、原因に関係なく役に立たない。
-mrog

「SDET」とは何ですか?
ピーターモーテンセン

1

テストコードをリファクタリングしてコピーアンドペーストを排除する場合、製品コードよりもテストコードの行が多いことは必ずしも問題ではありません。

問題は、ビジネスの意味を持たない実装のミラーであるテストがあることです。たとえば、モックとスタブをロードし、メソッドが他のメソッドを呼び出すことだけをテストすることです。

「ほとんどのユニットテストが無駄である理由」の論文で引用されているのは、ユニットテストには「正確で広範かつ正式で独立した神託、そして...ビジネス価値」があるべきだということです。


0

言及していなかったことの1つは、開発者がいつでも実行できるように、テストを迅速かつ簡単にする必要があるということです。

ソース管理にチェックインして、テストが完了するまで1時間以上(コードベースのサイズに応じて)待機して、変更が何かを壊したかどうかを確認する必要はありません。ソース管理にチェックインする前(または、少なくとも変更をプッシュする前)に自分のマシン。理想的には、単一のスクリプトまたはボタンを押すだけでテストを実行できるはずです。

また、これらのテストをローカルで実行する場合、数秒のオーダーで高速に実行する必要があります。それより遅いと、あなたはそれらを十分にまたはまったく実行しないように誘惑されるでしょう。

そのため、すべてのテストを実行するのに数分かかるほど多くのテストがあるか、または非常に複雑なテストがいくつかあることが問題になる可能性があります。

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