単体テストのコード品質?


23

単体テストを作成するとき、コードの品質と可読性を高めるために余分な時間を費やす価値はありますか?

テストを書くとき、より速く書くために、そして非常に多くの変数の使用を避けるために、私はしばしばDemeter法則を破ります。技術的には、単体テストは直接再利用されません-それらはコードに厳密にバインドされているため、それらに多くの時間を費やす理由は見当たりません。機能する必要があるだけです。


5
読みやすさと保守性は、単体テストの主な焦点である必要があります。
ELユスボフ

2
テストもコードです!
グラントペイリン

たとえ顧客に出荷されなくても、プロジェクトの一部です。それに応じて扱います。

回答:


11

品質と読みやすさの点で、実稼働コードよりも単体テストの方が優れていなければ、間違いなく同じことをする必要があります。多くの場合、ユニットテストは、コードの一部が何をするかを把握しようとするときに最初に見るものであり、読者はテストを見たときに何が問題かをすばやく理解する必要があります。単体テストも大きく変化する傾向があり、設計が堅牢でない場合、多くの点で問題が発生します。これは、テストを行う利点を無効にします。

デメテルの法則への違反は、その理由のためにあなたのユニットテストで間違いなく問題であり、私の心から外れた他の2つです:

  • テストがArrangeセクションまたはActセクションでDemeterの法則に違反する場合、ユニットテストはコードの別のコンシューマーであり、おそらくテスト対象のクラスを同じ場所で呼び出して操作するため、実稼働コードもそうである兆候です他の製品コードが行う方法。

  • テストがAssertセクションでDemeterの法則に違反する場合(つまり、テスト対象のオブジェクトの依存関係グラフに深くネストされたものの値を検証する場合)、それらは実際には単体テストではなく統合テストである可能性があります。言い換えると、TestAでABCDが何かに等しいと断言した場合、実際にAではなくDとAをテストしようとしている可能性があります。

ところで、あなたが言うとき

私は非常に頻繁にデメテルの法則を破ります。書くのが速くて、あまり多くの変数を使わないからです。

あなたが書いていることに注意する必要があります

var grab = myDependency.Grab;
var something = grab.Something;
var very = something.Very;

very.Deep();

デメテルの方が賢明ではありません

myDependency.Grab.Something.Very.Deep();

それがあなたが意味するものなら。


47

ユニットテストのために良質のコードを書くことに時間を費やすことは絶対に価値があります:

  • 他のコードと同様にメンテナンスが必要です。
  • 単体テストは、システムに最適なドキュメントのソースの1つであり、おそらく最も信頼性の高い形式です。彼らは本当に示す必要があります:
    • 意図:「予想される動作は何ですか?」。
    • 使用法:「このAPIを使用する方法は?」
  • 他のコードと同様にデバッグが必要です。

もう少しアドホックなアプローチを支持する1つの要因は、ユニットテストがパブリックAPIにならないため、どのインターフェイス/などを心配する必要がないことです。あなたが公開しています。


22

はい、それは重要です。単体テストを他のコードと同等の標準に保持する必要がある理由はいくつかあります。

  • 各ユニットテストは、受験者のドキュメントとしても機能します。テストが包括的で、可能な限り多くのエッジケースとエラー状態をカバーする場合、クラスまたは関数のコメントドキュメントを置き換えることができます。また、コードベースを初めて使用する人々の出発点としても役立ちます。

  • 単体テストにもバグがあります。また、コードが適切に記述されていると、エラーがより目立ちます。

  • 何らかの理由で、後でモジュールを分割する必要がある場合は、おそらくユニットテストも分割する必要があります。テストが簡単に識別できる依存関係を持つように記述されている場合、これは簡単です。

とはいえ、常に実用性の問題があります。コードの言語と性質によっては、テスト対象のコードよりもテストに多くの時間を費やさずに「クリーン」な単体テストを作成するのが難しい場合があります。その場合、私は通常、完全なカバレッジについてあまり心配することなく、簡単で迅速なものと最も重要な機能をテストすることに頼ります。バグが後で発生するたびに、そのテストを作成し、新しいテストと既存のテストをリファクタリングしてより良いものにできるかどうかを確認します。


12

ユニットテストを読んで、次に失敗したときにテストしているものを見つけることができない場合は、デバッグ時間の2倍を費やすことになります

正直なところ、ユニットテストには期待される結果が必要です。手順を実行します。実際の結果を得る; 記述と理解が容易な実際のタイプの構造に対してテストが期待されます


1

テストコードには、運用コードと同じくらいの愛情があります。読みやすさのために、おそらくもっと。あなた以外の人(コードを離れてから2週間後を含む)が何が起こっているかを理解することになっている場合は、コードをすっきりさせる必要があります。

これの意味は:

  • テストデータのビルドをビルダークラスに抽出します。
  • 複数のアサーションを個別のアサーションメソッドに抽出します。
  • ネーミングは非常に正確にしてください。Assert.That(x4, Is.EqualTo(y16*2*SOME_VALUE), ASS_ERR_TXT_56)ほとんどの読者にはほとんど意味がありません。

極端に言えば、テストは文章と同じくらい読みやすく理解しやすいように書くことができます。極端なテスターはおそらく、10行以上のユニットテストは悪いものだと言うでしょう。


1

最も重要な実際的な理由は、コードを変更するたびに、単体テストを変更することです。また、TDDを実行している場合は、最初にユニットテストを変更することもあります。

テストで次のいずれかを実行します。

  • 重複コード
  • 読みやすさを低下させる
  • 密結合
  • 時間結合
  • 高度な循環的複雑度(多くの依存関係)

また、変更が必要な場合は、多くの作業を行っています。

提案されたようにテストを処理すると、後悔することになります。「TDDが機能しない」という誤った結論に達する可能性があります。


0

これらの単体テストが「一時的」かどうかによって異なります。もし

  1. テストは頻繁に使用されます。

  2. 開発者は、他の開発者が作成した単体テストを使用する必要があります。

  3. ほとんどのテストは単体テストによって行われます

その後、テストを適切に記述する必要があります。テスト自体にバグがある場合、特にテストが書かれてから時間が経過した場合、バグを見つけて修正することは困難です。

一方、これらのテストが開発者自身によってのみ使用される場合、私はそれが大丈夫だと思うよりも。しかし、それでも「読み取り可能な」コードを書くことがより望ましいです。ラチェットフリークが言ったように、テストを適切に書くことに費やすよりも多くの時間をテストの修正に費やすことになります。


でも、自分のために- (1)ユニットテストは、あなたがすべての詳細を覚えていないだろう、彼らは1ヶ月で、あなたの自己のためにしている(またはそれ以上)の場合でも、(2)一時的なことはありません、したがって、それを正しく行うことが重要である
BЈовић
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.