どれだけあざけることが「ちょうどいい」ですか?


10

「依存する」と確信しているので、冗談めかして質問にタイトルを付けましたが、特定の質問があります。

多くの依存関係の深い層を持つソフトウェアで作業している私のチームは、モックをかなり広範囲に使用して、各コードモジュールをその下の依存関係から分離することに慣れています。

したがって、このビデオロイ・オセロベが5%程度の時間だけモックを使用すべきであると示唆していることに驚きました。私たちは70-90%のどこかに座っていると思います。他の同様のガイダンスも時々見ました。

私は「統合テスト」の2つのカテゴリーと見なすものを定義する必要があります。これらは非常に異なるため、実際には異なる名前を付ける必要があります。1)複数のコードモジュールを統合するインプロセステストと2)話し合うアウトプロセステストデータベース、ファイルシステム、Webサービスなどに対応しています。私が関心を持っているのはタイプ1で、複数のコードモジュールをすべてインプロセスで統合するテストです。

私が読んだコミュニティガイダンスの多くは、単体テストは正確な場所に関する正確なフィードバックを提供するため、多数の分離された細粒度の単体テストと少数の粗粒度のエンドツーエンド統合テストを優先する必要があることを示唆しています回帰が作成された可能性がありますが、セットアップが面倒な大まかなテストは、実際にはシステムのエンドツーエンドの機能をより多く検証します。

このため、これらの個別のコード単位を分離するには、モッキングをかなり頻繁に使用する必要があるようです。

次のようなオブジェクトモデルがあるとします。

ここに画像の説明を入力してください

...また、アプリケーションの依存関係の深さは、この画像に収められるよりもはるかに深くなるため、2〜4層と5〜13層の間に複数の層Nがあることを考慮してください。

ユニット#1で行われている簡単な論理決定をテストする場合、およびすべての依存関係がそれに依存するコードモジュールにコンストラクター注入されている場合、たとえば、2、3、および4は、モジュール1にコンストラクター注入されます。画像では、2、3、および4のモックを1に注入するほうがはるかに便利です。

それ以外の場合は、2、3、および4の具象インスタンスを作成する必要があります。これは、追加のタイピングだけでは難しい場合があります。多くの場合、2、3、および4は、コンストラクター要件を満たし、グラフに従って(およびプロジェクトの現実に従って)、困難な場合があります。Nから13の具体的なインスタンスを構築して、 2、3、4。

この状況は、2、3、または4が特定の方法で動作して、#1の単純な論理決定をテストできるようにする必要がある場合、より困難になります。2、3、または4が必要な動作をするようにするには、オブジェクトグラフ/ツリー全体を一度に理解し、「精神的に推論する」必要があるかもしれません。多くの場合、myMockOfModule2.Setup(x => x.GoLeftOrRight())。Returns(new Right());を実行する方がはるかに簡単です。モジュール2が正しく進むように指示したときに、モジュール1が期待どおりに応答することをテストします。

2 ... N ... 13の具象インスタンスをすべて一緒にテストすると、テスト設定は非常に大きくなり、ほとんどが重複します。テストの失敗は、リグレッションの失敗の場所を正確に特定するのに非常に適しているとは限りません。テストは独立していません(別のサポートリンク)。

当然のことながら、これらのモジュールがそれ以上依存することはほとんどないため、最下層の相互作用ベースのテストではなく、状態ベースのテストを行うことは、しばしば妥当です。しかし、モジュールを一番下より上に分離するために、モッキングが定義上ほとんど必要であるようです。

このすべてを踏まえて、私が欠けているかもしれないものを誰かに教えてもらえますか?私たちのチームはモックを使いすぎていませんか?あるいは、ほとんどのアプリケーションの依存関係の層が十分に浅く、統合されたすべてのコードモジュールをテストすることが実際に合理的である(私たちのケースを「特別な」ものにする)と、通常の単体テストガイダンスに何らかの仮定があるのでしょうか。あるいは、おそらく別の方法として、私たちのチームは私たちの制限されたコンテキストを適切に制限していませんか?


あなたのアプリケーションが疎結合の恩恵を受けることができるように私には聞こえます。 en.wikipedia.org/wiki/Loose_coupling
Robert Harvey

1
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")? <-これ。
Robert Harvey

また、注目に値します:回帰テスト(特に統合テスト)の目的は、ソフトウェアがまだ機能していることを証明することであり、必ずしもどこで問題が発生するかを特定することではありません。トラブルシューティングでそれを行い、問題を修正してから、追加の単体テストで特定の破損をカバーできます。
Robert Harvey

元の投稿では、モジュール1はI2、I3、およびI4のみを認識していると言って、より明確であったはずです。モジュール2は、I5、I6、およびI7のみを認識します。私が説明した課題につながる具体的な2、3、および4対1を提供するのは、モックを使用しないテストの疑わしい目標だけです。それ以外の場合は、5%をはるかに超える時間でモックを使用します。
ardave 2013年

多くのチームが自分たちの状況を「特別」だと誤って感じていたため、貴重な大会に挑んでいるというブログ記事を読んだ後、私は私たちのケースが「特別」であると冗談を言った。しかし、これが実際に私たちのケースである場合、これは私が読んだいくつかのコミュニティガイダンスと私のチームの実際の経験のいくつかとの間の相違を説明するでしょう。(5%vs 70-90%)
ardave 2013年

回答:


4

私たちのチームはモックを使いすぎていませんか?

一見ではありません。

1..13モジュールがある場合、それぞれに独自の単体テストがあり、すべての(重要ではない、信頼できない)依存関係はテストバージョンに置き換える必要があります。それモック意味するかもしれませんが、一部の人々は命名に慣れているため、偽物、シム、nullオブジェクト...すべてのテスト実装を「モック」と呼ぶ人もいます。これは、どれほど「正しい」かに関する混乱の原因かもしれません。

個人的には、すべてのテストオブジェクトを「モック」と呼んでいます。さまざまなオブジェクトを区別することはあまり役に立たないことが多いためです。彼らが私のユニットテストを速く、隔離し、回復力がある限り...私は彼らが何と名付けられたか気にしません。


それでは、コードモジュールを分離してテストするのと、統合された複数のコードモジュールをテストするのが最適な時期について、一般的なガイダンスがあるどうか疑問に思います。他の方法では分離できた可能性のある2つのモジュールを統合するとすぐに、多くの望ましくない問題に直面します:回帰の原因の特定の欠如/単一の回帰での複数のテストの失敗、過度のテストセットアップなど。私は自分の直感的な感覚(「テストを聞く」)を持っていますが、これにより70〜90%の模擬レベルに留まります。
ardave 2013年

1
@nono-私の経験では、あなたが言及する理由のために、すべてを個別にテストする必要があります。単体テストで単体テストできないのは、ファイルシステムや他の外部リソースに直接対抗するためにできないことだけです(結局、何かを実行する必要があります)。
Telastyn 2013年

数日間これを噛んだ後、あなたの説明は可能な限り最高の説明のようです:ダミーのテストダブルまたは対照的に、「モック」の厳密な定義を遡及的相互作用/動作検証に使用されるテストダブルのタイプとして使用する場合いくつかの特定の動作をシミュレートするために事前に構成されたテストdouble。そうすれば、5%レベルで終了することがわかりました。
ardave 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.