単体テストについて話すとき、「DAMP not DRY」とはどういう意味ですか?


345

ユニットテスト(nUnit、jUnit、xUnitなど)は

DAMPDRYではありません

(たとえば、ユニットテストには「ドライコード」ではなく「ダンプコード」を含める必要があります)

彼らは何を話している?


2
非DRYコードを保証する単体テストについて特別なことは何もありません。非DRYテストを書くことは、怠惰なプログラマーがその怠惰のために領域を切り開くことを試みる言い訳です。簡単に言うと、DRYnessと読みやすさは直交する問題です。
Acumenus 2017

2
DRYnessはコードナビゲーション距離を増加させ、その結果、理解するための精神的負荷が高くなります。これは、「通常の」テキストベースの環境で成り立ちます。射影エディターは、コードの直交性を低下させる可能性がありますが、すべての場合ではありません。
ピーター

回答:


595

それは矛盾ではなくバランスです

DAMPとDRYは矛盾せず、コードの保守性の2つの異なる側面のバランスをとっています。保守可能なコード(変更が容易なコード)は、ここでの最終的な目標です。

DAMP(記述的で意味のあるフレーズ)は、コードの読みやすさを促進します。

コードを維持するには、まずコードを理解する必要があります。それを理解するには、それを読む必要があります。少しの間、コードの読み取りにどのくらいの時間を費やしているか考えてください。それは多い。 DAMPは、コードを読んで理解するのに必要な時間を短縮することにより、保守性を向上させます。

DRY(自分を繰り返さないでください)は、コードの直交性を促進します。

重複を削除すると、システム内のすべての概念がコード内で単一の信頼できる表現を持つことが保証されます。1つのビジネスコンセプトを変更すると、コードも1つ変更されます。DRYは、システムの変更が必要な部分のみに変更(リスク)を分離することにより、保守性を向上させます。

では、テストで複製が受け入れられるのはなぜですか?

テストでは、わずかに異なる入力値またはセットアップコードでのみ同じものを繰り返しテストするため、多くの場合、固有の重複が含まれます。ただし、量産コードとは異なり、この複製は通常、単一のテストフィクスチャ/ファイル内のシナリオにのみ分離されます。このため、複製は最小限で明白であり、他の種類の複製よりもプロジェクトのリスクが低くなります。

さらに、この種の重複を削除すると、テストの可読性が低下します。以前に各テストで複製された詳細は、いくつかの新しいメソッドまたはクラスで隠されています。テストの全体像を把握するには、これらすべてのピースを精神的に元に戻す必要があります。

したがって、テストコードの複製は、リスクが少なく、読みやすくなるため、許容できると見なされる方法を簡単に確認できます。

原則として、量産コードではDRYを使用し、テストコードではDAMPを使用します。どちらも同じように重要ですが、少しの知恵があれば、バランスを傾けることができます。


18
これはすばらしい簡潔な要約です。また、DAMPテストは要件の変更に対してより弾力性があり、テストの自明性を測定することは、新しい要件に合わせてテストを書き直すことを他の誰かに課せられた場合に非常に役立ちます。Jesper Lundbergもこの問題について良い論文を書いています。
Jason 14

3
@ Jason、Btwは「Jesper Lundbergもこのテーマに関して優れた論文を持っている」へのリンクはありますか?
Pacerier、2015

2
@JohnSaunders、テストデータビルダーパターンを使用することでその重複の一部を回避できます:natpryce.com/articles/000714.html
si618

2
テストコードをドライアウトすると、ミステリーゲストを
jayeff

1
また、上手に書かれたテストは、基本的にはアプリケーションのドキュメント/コメントであることも付け加えておきます。したがって、より説明的であることは、他の開発者にあなたの意図を説明するのに役立ちます。そしてOPが言うように、それらは各テストに自己完結しているので、アプリケーションへの危険は最小限です。最悪のシナリオは、冗長なテストまたはテストセットアップがあり、テストスイートの実行に時間がかかることです。テストカバレッジが良いという点では、むしろ誤りを犯します。
Lee McAlilly、2018年

60

DAMP-説明的で意味のあるフレーズ。

「DAMP not DRY」は、コードの再利用よりも読みやすさを重視しています。テストケースでDRYではなくDAMPを使用するという考え方は、テストケースにコードが繰り返し含まれる場合があるとしても、テストは理解しやすいということです。

参照してください。ユニットテストでの重複したコードより耐えられますか?この視点のメリットについてのいくつかの議論のため。

これは、ドメイン固有言語に関連して、Jay Fieldsによって作成された可能性があります。


1
良い答えと関連する質問へのリンク。完全なDAMPとDRYの選択はありません。私たちは、可能な限りドライであり、テストが理解しにくくなるほどドライではないコードを求めています。テストが失敗したときは、理由を明確にして、開発者がSUTの修正を開始できるようにしたいと思います。つまり、テストではDAMPコードを使用します。ほとんどのプログラミング概念と同様に、何かを行き過ぎることは常に可能です。単体テストコードが非常に乾燥しているために、テストが失敗した理由と理由を特定するのに長時間かかる場合、「乾燥しすぎている」可能性があります。
ジェラルドデイビス

29

「DRY」は「自分を繰り返さないで」

これは、再利用可能なコードを書くように人々に指示するために使用される用語であり、その結果、同じようなコードを何度も何度も作成することはありません。

「DAMP」は「説明的で意味のあるフレーズ」です。

この用語は、それを見ている人が簡単に理解できるコードを書くように指示することを目的としています。この原則に従えば、長くてわかりやすい変数名や関数名などができます。


15
AIUI、DRYは、再利用によって時間を節約するだけの問題ではありません。また、異なるコードパスが「非同期」になるのを防ぎます。同じロジックを複数のクラスにコピーして貼り付ける場合、変更が必要な場合は、そのコードのすべてのインスタンスを更新する必要があります。(そして、必然的にそれらの1つは動作せず、運動すると爆破します。)
Andrzej Doyle

20

ダンプ=「説明的で意味のあるフレーズ」-ユニットテストは「読み取り」できるはずです。

読みやすさは、冗長なコードを回避することよりも重要です。

記事から:

DAMPは「説明的で意味のあるフレーズ」の略であり、DRYの反対であり、「すべてがゴミの山のように見えて読み取り不可能である必要がある」という意味ではなく、冗長なコードを回避するよりも読みやすさが重要です。

これは何を意味し、どこで使用するのですか?

DAMPは主にテストコードを記述するときに適用されます。テストコードは、ある程度の冗長性が許容できる程度まで、非常に理解しやすいものでなければなりません。



11

ここにはすでにいくつかの回答がありますが、必ずしも説明できるとは限らないので、もう1つ追加したいと思いました。

DRY(自分を繰り返さないでください)の考え方は、アプリケーションコードでは冗長なコードや反復的なコードを避けたいということです。コードで複数回実行する必要のあるものがあれば、いくつかの場所で同様のコードを繰り返すのではなく、関数またはクラスを用意する必要があります。

これはかなりよく知られたプログラミング概念です。

DAMP(記述的で意味のあるフレーズ)は、単体テスト用です。ここでの考え方は、単体テストのメソッド名は長くて説明的である必要があるということです-何をテストしているのかを説明する効果的な短い文章です。

例えば: testWhenIAddOneAndOneIShouldGetTwo() { .... }

このようなDAMPメソッド名を読み取る場合、テストコードを読み取る必要がなくても、テスト作成者が達成しようとしていたことを正確に理解する必要があります(ただし、テストコードはこの概念に加えて、当然のことながら、変数名が長いため、等)。

ユニットテストメソッドには非常に具体的な入力と期待される出力があるため、これが可能であり、DAMPの原理はそれらに対してうまく機能します。メインのアプリケーションコードのメソッドは、特にDRYの原則を念頭に置いて記述した場合は、このような名前を保証するほど具体的である可能性は低いです。

DAMPとDRYは互いに矛盾しません-コードの記述方法のさまざまな側面をカバーします-それでも、DRYの原則を念頭に置いて記述されたメソッドは汎用的であり、適している可能性が低いため、通常は一緒に使用されません非常に具体的なメソッド名に。したがって、一般に、上記で説明したように、アプリケーションコードはDRYであり、ユニットテストコードはDAMPである必要があります。

私はそれが少し良く説明するのに役立つことを願っています。


5

私はクリス・エドワーズに同意しますが、両者のバランスをとる必要があります。もう1つ注意すべき点は、重複を削除しようとして、ユニットテストコードに多くの追加の構造を追加することになった場合(つまり、DRYを極端にする場合)、そこにバグが発生するリスクがあることです。このような状況では、ユニットテストをユニットテストするか、構造のビットをテストしないでおく必要があります。


0

ここでの取り組みを再現したくありませんが、DAMPであるがDRYの利点を備えたテストを行うことができます。反対に、DRYテストはDAMPテストを満たさない場合があります。

いくつかの例を含むDRYとDAMPについてブログを書きました。

どちらのアプローチもあなたの唯一の解決策であってはなりません、時々DAMPはやり過ぎです、他の時は非常に素晴らしい追加です。

一般的なルールとして、3つのルールを適用する必要があります。3回目に重複を見つけた場合は、DAMPスタイルのテストを作成することを検討する価値がありますが、それでもすべての重複が悪いわけではありません。コンテキストが重要です。

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