失敗した単体テストのチェックの価値は何ですか?


13

単体テストが実行されないようにする方法はありますが、失敗した単体テストをチェックすることの価値は何ですか?

簡単な例を使用します:大文字と小文字の区別。現在のコードでは大文字と小文字が区別されます。メソッドへの有効な入力は「Cat」であり、Animal.Catの列挙を返します。ただし、メソッドの目的の機能では大文字と小文字を区別しないでください。したがって、記述されたメソッドが「cat」に渡された場合、Animal.CatではなくAnimal.Nullのようなものを返す可能性があり、ユニットテストは失敗します。簡単なコード変更でこの作業が可能になりますが、より複雑な問題の修正には数週間かかる場合がありますが、単体テストでバグを特定することはそれほど複雑ではありません。

現在分析中のアプリケーションには、「機能する」4年間のコードがあります。ただし、単体テストに関する最近の議論では、コードに欠陥が見つかりました。明示的な実装ドキュメント(大文字と小文字を区別するかどうかなど)、または現在の呼び出し方法に基づいてバグを実行しないコードのみが必要なものもあります。ただし、バグが発生する有効な入力である特定のシナリオを実行する単体テストを作成できます。

誰かがコードを修正できるようになるまでバグを実行する単体テストをチェックインすることの価値は何ですか?

実行されたテストに基づいてビルドが成功したかどうかを判断するために、このユニットテストにignore、priority、categoryなどのフラグを設定する必要がありますか?最終的には、誰かが修正したらコードを実行するために単体テストを作成する必要があります。

一方では、特定されたバグが修正されていないことを示しています。一方、ログには何百もの失敗した単体テストがあり、コードチェックインによる失敗と失敗の組み合わせを見つけるのは困難です。


これは、これらのテストカバレッジ数を増やす1つの方法です。
ジェフ

ユニットテストを作成するための努力を既に行っている場合、問題を解決することにしたのに、なぜユニットテストを書き直さなければならないのでしょうか。チェックインされているからといって、スイートで実行する必要があるという意味ではありません。(「既知の問題」のカテゴリを作成し、それらのテストをバックログ/ TODOリストとして扱うことができます。)
カレブ

回答:


17

私は壊れたユニットテストがでチェックされていないように行う彼らは、不要なノイズを生成しているため。すべてのユニットテストの後、すべての失敗した問題をチェックする必要があります(赤)。新しい問題があるか、または修正/修正するための古いオープンがあるため、赤です。20を超えるユニットテストがある場合、これは大丈夫ではありません。

代わりに私は使用します

  • [Ignore("Reason")]結果を黄色にする属性または
  • throw new NotImplementedException()結果が灰色になります

注:私は.netにNUnitを使用しています。「グレー」機能が他の単体テストフレームワークにあるかどうかはわかりません。

したがって、ユニットテスト結果の次の意味が好きです。

  • 緑:すべて終了
  • 灰色:実行する必要があるが、優先度が低い計画された新機能
  • 黄色:バグはまだ修正されていません。すぐに修正する必要があります
  • 赤:新しいバグ。すぐに修正する必要があります

「赤」以外はすべてチェックインできます。

質問に答えるには、「red-failed-testes」でチェックする値よりも害がありますが、「yellow-ignored-tests」または「grey-NotImplementedYet-tests」でチェックすることは、todoリストとして役立ちます。


私がこのアプローチで見た問題は、無視されたテストがおそらく修正されないことです。また、テストコード全体を削除することもできますが、違いは何でしょうか(ここでは少し生意気です)
ロヴィス

4
will probably never be fixedeffordを自動テストに費やすかどうかは政治的な決定です。「無視されたテスト」を使用すると、それらを修正する機会があります。「無視されたテスト」を捨てるということは、「自動テストを
次々に

8

これが業界標準のふりをするつもりはありませんが、コードまたは単体テスト自体に問題があることを自分または他のプロジェクトメンバーに思い出させる方法として、壊れたテストをチェックインします。

考慮すべきことの1つは、開発ポリシーがペナルティなしで失敗したテストを許可するかどうかです。私はテスト駆動開発を行うショップで働いている友人がいるので、彼らは常にテストの失敗から始めます...


5
ただし、失敗したテストはチェックインしないでください。ビルドサーバーはテストが壊れたプロジェクトをビルドするべきではないからです。
CaffGeek

@Chad:ビルドとテストは、1つの自動化されたステップの2つの別個の部分です。ビルドにより、すべてがコンパイルされます。テストにより、ビルドの結果が有効であることを確認します。私の質問の解釈は、「コンパイルしないコードをチェックインする必要がありますか?」ではありませんでした。代わりに、「失敗することがわかっているテストをチェックインする必要がありますか?」
-unholysampler

1
考慮すべき点を追加するだけで、一部の継続的統合ビルドサーバーはテストを実行しますが、失敗した場合は展開されません。当然、ビルドが失敗したかのようにコードが失敗し、壊れていることがわかっている製品を展開しても意味がありません。
CaffGeek

@Chad:そうです、CIサーバーを完全に忘れていました。それは間違いなく考慮すべき点でしょう。「壊れた」テストの意味を明確にすることも価値があります。それらは単なる「悪い」テストですか、それともAPIが何らかの方法で変更されたためにテストが失敗しているのですか?
タイソンT.

問題はもっと明確になっているはずです。テストはコンパイルされますが、期待される結果は失敗します。

6

ユニットテストに失敗すると、開発チームは合意された仕様に準拠するために何をする必要があるかを把握できます。

要するに、失敗した単体テストはチームに「TODO」リストを与えます。

このため、ユニットテストの失敗は、ユニットテストをまったく行わないよりもはるかに優れてい
ます。仕様は手動で繰り返し確認する必要があります。

[*単体テストが実際に何か有用なものをテストすることを提供した。]


2
ホワイトボード、To Doリストアプリ、問題追跡システムなど、To Doリストを維持するより良い方法があります。常に完全に合格すると予想される場合、テストスイートを使用する方がはるかに簡単であり、表示されるテストの失敗はすぐに修正する新しい問題です。
bdsl

6

単体テストの目的は、システムの予想される動作をアサートすることであり、欠陥を文書化することではありません。単体テストを使用して欠陥を文書化すると、期待される動作をアサートするためのそれらの有用性が低下します。「このテストが失敗した理由」という質問に対する答え。単純な「ああ、壊れるとは思っていなかった何かが壊れている」テストの失敗が予想されるか予期しないかは不明になりました。

これは、レガシーコードの効果的な使用の第13章の最初からの段落です。

自動化された単体テストは非常に重要なツールですが、バグの発見には適していません。少なくとも直接ではありません。一般に、自動化されたテストでは、達成したい目標を指定するか、すでに存在する動作を維持しようとします。開発の自然な流れでは、指定するテストはを保持するテストになります。バグは見つかりますが、通常はテストを初めて実行するときは見つかりません。予期しない動作を変更すると、後の実行でバグが見つかります。


3

しかし、新しいプロジェクトのバグを識別する壊れたものは、そのような名前が付けられています。そうすれば、それらが壊れているはずです...修正されると、緑色に変わり、通常のテストスイートに移動します。

注:ビルドサーバーがビルドを中断するチェックインを防止する場合、そのプロジェクトはビルドサーバー上でビルドされないように設定する必要があります(すべてのテストに合格しないものとして壊れたビルドを定義すると仮定します)


+1重要な引数があるかどうかをチェックインするかどうかの答えはありませんが:サーバーのビルド
k3b

そのようなテストを別のプロジェクトに移動するのではなく、属性を使用してそのようなテストをマークしたいです。
CodesInChaos

2

単体テストでは、関数の成功事例に加えてエラー事例もテストする必要があります。関数は、不正な入力を明示的に拒否するか、どの入力が有効と見なされるかを説明するドキュメントを用意する必要があります。

これらのいずれも実行していない関数がある場合、それはバグであり、それが存在することを記録する方法が必要です。この問題を実証する単体テストを作成することは、そのための1つの方法です。バグチケットの提出も別のオプションです。

単体テストのポイントは、100%成功することではなく、コードのバグを見つけて修正することです。テストを行わないことは100%成功するための簡単な方法ですが、それはプロジェクトにとってあまり有益ではありません。


うわ...「ユニットテストのポイントは、100%成功することではない」と、彼らはすべて合格する必要はないということですか?
CaffGeek

2
@Chad:ポイントは、失敗することがわかっているテストがある方が良いということですが、夜間のビルド/テストの最後に緑色のチェックマークを付けることができるように、テストがないのではなく、実際の問題を示しています。
-unholysampler

8
@unholysamplerは、「別のプロジェクトにいることによって」「should」ブレークとして明確にマークされていない限り、テストが壊れたことはありません。そうしないと、それらはノイズになり、合格するはずのテストがいつ中断されたかわかりません。それは完全に継続的インテグレーションとなるユニットテストの目的破る
CaffGeek

2
@Chad:これは定義の意味論になっていると思います。OPに基づいて、彼はバグを行使する有効なテストの作成について話しているように聞こえました。ただし、バグの優先度は低く、すぐに修正される可能性は低いです。継続的インテグレーションをもたらしたのはあなたであり、自動化されたプロセスにより厳しい制限を課しています。
-unholysampler

4
@ unholysampler、CI、またはCIなし、ポイントは、テストを実行し、いくつかの赤信号を見ることに慣れているとき、それに慣れることです。 それで、緑だったものが赤に変わったら...どうやって知っていますか?!? それは恐ろしい習慣であり、多くの組織でテストが受け入れられない理由の1つです。
CaffGeek

1

失敗するたびにバグを報告し、テスト結果に注意してください。その後、行動をまとめてバグを修正した場合、テストに合格し、テスト結果から削除します。問題を無視しないでください。


-3

未完成コードのテストの実装でTDDがどのように行われるかは、最初に[ExpectedException]属性などでテストを記述してください。不完全なコードにはロジックが含まれていないため、これは最初に渡され、throw new Exception()コードが書き込まれます。例外を通過することは間違っていますが、これによりテストは最初に合格し、チェックインに適合します。無視されたテストを忘れるかもしれませんが、不完全なコードを完全に整理したり埋めたりする可能性があります。これを行うと、例外を予期していた対応するテストが自動的に失敗し始め、修正するよう警告されます。これには、ExpectExceptionを取り除き、代わりに実際のアサートを行うためのテストのわずかな変更が含まれる場合があります。CI、開発者、テスター、顧客はすべて幸せで、Win-Winの状況ですか?


1
これは質問に答えません。TDDとは何か、なぜ予想される例外をテストするのかは問いません。
アンディWiesendanger
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.