バグを修正するときは、常にユニットテストを行うべきですか?


29

バグを修正する場合、最初に特定のバグで失敗するテストを記述し、次にテストが合格するまでコードを修正することをお勧めします。これはTDDのプラクティスに従っており、良いプラクティスであると想定されていますが、実装に非常に近い不可解なテストを作成する傾向があることに気付きました。

たとえば、ジョブが送信され、特定の状態に到達し、中止され、再試行されたときに問題が発生しました。このバグを再現するために、スレッド同期、多くのモックなどを含む大規模なテストが作成されました...それは仕事をしましたが、コードをリファクタリングしているので、このマンモスを削除するだけで非常に魅力的です新しいデザインに合わせるには、本当に多くの作業が(再び)必要になります。そして、1つの特定のケースで1つの小さな機能をテストするだけです。

したがって、私の質問:再現が難しいバグをどのようにテストしますか?実装をテストし、リファクタリングと可読性を損なうものを作成しないようにするにはどうすればよいですか?


そのエラーケースは新しいデザインに関連していますか?私にとって新しいデザインの一部はデザインの信頼性を高めることなので、この種のバグが元のデザインの間違いと関係がある場合、このテストケースを削除することを正当化するためにそれを使用できるかもしれません。
チミン

リファクタリングは他の何かに関するものであり、新しいデザインでは、コードをわずかに変更し、テストを監視しているバグを再導入することが依然として可能です。テストの代替案は、「これと性交しないでください」というコード内のコメントになると思いますが、それは間違っているように聞こえます:p
Zonko

1
単体テストとしては複雑すぎて統合テストの一部にする場合
ラチェットフリーク

このようなサウンドには、単体テストではなく統合テストが必要です。あなたがそんなにm笑しているという事実に基づいています。私が見た一般的なルールは、コードベースの外部のコンポーネントと通信するコード(データベースと通信したり、ファイルシステムから読み取ったり)をテストしないことです。
ルーカス

回答:


27

はい、一般的にはすべきです。すべてのガイドラインと同様に、他のガイドラインに反する場合は最善の判断を下す必要があります。このシナリオでは、テストの実装に必要な作業と、ビジネスの問題をターゲットにしてバグの状態の回帰をキャッチするテストの品質と、バグの重大度を比較する必要があります。

バグを実行するための中断は、単純に単体テストを開発して維持するよりもオーバーヘッドが多い傾向があるため、私はテストを書くよりもテストを書く方を好む傾向があります。


私はこれをさらに強調し、理想的な世界では、失敗した単体テストが存在する場合にのみバグと見なされるが、イタリック体の場合は+1、ビジネスニーズ優先されることに注意することを述べます。
ジョシュアドレイク

2
実際、最終的には、テストを維持するのに必要な時間と、noobがバグが再度発生した場合にそれを検出して修正するのにかかる時間とのバランスが重要です。
ゾンコ

。それはちょうどそれがある特定の状態に達したときに、ジョブを中止し、再試行テストではなく、中止と仕事がで可能性があり、すべての状態で再試行テストしていないように、私はまた、テストを一般有利に働く
オールド・プロ

+1は「単純に単体テストを開発して維持するよりも、バグが実行を中断するため、オーバーヘッドが大きくなる傾向がある」ためです。
ピーターK.

16

ベストプラクティス-私はよく従わないことを恥ずかしく思いますが、生産で観察された問題を実証するシステムまたは統合テストを作成し、問題の原因となるユニットを見つけるために調査することです、そして、ユニットレベルで問題を示すユニットのユニットテストを記述します。ユニットテストを取得したら、ユニットを修正し、すべてのテストを実行します。この時点で、元のテストは壊れやすいか遅いため、破棄するのが賢明かもしれませんが、リグレッションとカバレッジのためにユニットテストを自動化スイートに保持します。


7

欠陥を特定するためのテストを作成することは、欠陥を再現し、修正されたことを確認するために必要な手順を正確に特定できるため、良いアイデアです。さらに、これらのテストはスモークテストまたはリグレッションテストの一部として実行でき、後の変更によってシステムに古い欠陥が再導入されないことを確認できます。

最初に考慮すべきことは、必要なテストのレベルです。おそらく、修正を検証するためのテストは、システムレベルで、または手動で行われる受け入れテストでさえ、より適切でしょう。具体的にどのように実装されているかに関係なく、文書化され管理されているテストを持つことがより重要だと思います。

リファクタリングがテストに与える影響に関する限り、それは特定の特性に依存します。場合によっては、リファクタリング(または新機能などのあらゆる種類の作業)により、テストが不要になる場合があります。最初に発生した問題は、もはや発生しない可能性があります。その場合、可能性のあるテストからテストを削除して、テストプロセス(自動または手動)をよりリーンにすることが賢明かもしれません。その他の場合、テストを実行し、異なるレベルで機能を検証する方がより適切な複数の方法があります。機能がマイナーな場合、おそらくテストはまったく必要ありません。

また、テストに依存するだけでなく、ロギングも考慮することができます。たとえば、実行時に情報をキャプチャします(環境に応じてさまざまなレベルの詳細度を使用します-テスト中はより詳細に、展開中は詳細になりません)、アプリケーションのプロファイリング、システムの現在の状態のダンプを取得します。問題の一般的なトリガーを見つけることができる場合は、それを使用して、すべてのレベルでテストをガイドできます。


5

はい、そうすべきです。

既存のコードベースの単体テストを記述します。バグを修正するときは、ユニットテストが失敗することを確認する必要があります。これにより、実際にバグに取り組んでいるという自信が得られます。次に、バグを修正してリファクタリングし、テストに合格する必要があります。

ただし、これはTDDのプラクティスではありません。TDDではテストが設計を推進しますが、あなたの場合、設計はすでに決定されています。

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