単体テストは「機能的な」ソフトウェアのみを対象とすべきか


9

新しいソフトウェア開発プロジェクトでStructureMapを使用しています。チームメンバーの1人が、基本的にStructureMapコンテナー構成をテストする単体テストを実装しました。これを行うには、次のようにします。

  • アプリケーションの名前空間のクラスに構成されているアセンブリのインスタンスの数をカウントします。
  • クラスレベルで予期されるインスタンスを定義します
  • 予想されるインスタンスが見つかったインスタンスの総数と一致することを表明します。
  • 予想されるインスタンスがテストで定義されたインスタンスと一致することを表明する

この例は次のとおりです。

var repositories = container.GetAllInstances<IEnvironmentRepository>();
Assert.AreEqual(1, repositories .Count());
foundInstances = foundInstances + repositories .Count();

次のクラスの「単体テスト」もあります。

public MyClass(IEnvironmentRepository environmentRepository)
        {

        }

これらのテストでは、IEnvironmentRepositoryをモックしているため、ライブシステムで発生するようなコンテナーからの注入は行いません。

同僚は、「ユニットテストはそれ自体の構成のみをテストする」というコメントを付けて、structuremap configのユニットテストを無視しました。これは明らかにテストの目的であり、私の意見では完全に有効です。テストを無視した人に構造テストの構成を削除してIEnvironmentRepository(テストはまだ無視されています)、完全な単体テストスイートを実行するように依頼したところ、すべて成功しました。次に、アプリケーションを実行しましたが、コンテナー構成が無効になったため、アプリケーションが倒れました。私の意見では、これはテストの価値を証明しました、私の同僚はまだ反対しました。彼は単に構成をテストするべきではないと述べましたが、これは単体テストの範囲内であると私は思います。

したがって、いくつかの質問があります。

  • それは有効な単体テストですか?ストラクチャマップが機能するのではなく、コンテナの構成をテストしています(ただし、重複が確認できます)
  • そうでない場合、テストせずに構成を検証するにはどうすればよいですか。誰かが誤って必要なコード行を削除してチェックインしないようにするにはどうすればよいですか?
  • なければならないMyClassユニットテストは、のインスタンスを解決IEnvironmentRepositoryコンテナからとでこれを渡しますか?

10
テストに関する10件の意見の相違のうち9件は、フレームワークがすべての形式の自動テストをサポートしており、特定の自動テストが適切で適切な単体テストであるかどうかのセマンティクスを求めているためです。あなたが説明するテストは一種のnot-quite-unit-test-testのように聞こえますが、自動化(そしてチェックイン時に実行)するのに非常に役立つ場合があります-単体テストと呼ばないでください。テストが明確に分離された独自の機能/フォルダーに住んでいた場合、同僚が夜によく眠れるかどうか尋ねます。
Jeroen Mostert 2017

2
それは私の意見でもあり、おそらく有用であり、厳密に単体テストではありませんが、付加価値を提供し、これは証明されています。彼の反応は、他の単体テストがこれを拾っただろうというものでしたが、私の意見では、それらが厳密な単体テストとして書かれていると、依存関係をあざけるので、それを使用するまで構成が有効であるかどうかわかりません。
ChrisBint 2017

4
同僚が構成をテストしないと言ったのは、実際の展開ごとに異なる可能性がある本物の構成はテストできない/テストできないからです。「赤」は間違っていて「青」はそうではないというのは誰ですか?テストは1つのセットアップに密接に結び付けられます。ただし、コードのアーティファクトに関連付けられている構成は、多少の例外があります。これは、構成が変化せず、間違いを犯す方法が明らかにあるためです。理想的には、DRYメタデータからビルド時にそのような構成を生成することになりますが、これが実行不可能な場合、このようなテストは付加価値をもたらします。回避可能な展開エラーよりも優れています。
Jeroen Mostert 2017

2
あなたが説明しているのはユニットをテストするのではなく、サードパーティのソフトウェアの構成をテストします。それは幻想だ便利なこれらの事をテストするテストを持っているが、彼らは意見の相違のルートがあるかもしれない統合テストではなく、ユニットテスト、および切断されています。
Phoshi 2017

3
@ChrisBint Goodness礼儀正しいいいえ、私は自分でコンテナテストの束を書きました。それらには多くの価値があり、ユニットテストではありません。それは問題ありません。統合テストは、単体テストではできないことを把握するために非常に価値があります。
Phoshi 2017

回答:


13

これは完全に有効な自動テストです。コードベースの骨格コンポーネントの健全性を検証するため、これらを「アーキテクチャテスト」と呼びます。

IoCコンテナーは、アプリケーション内のすべてのオブジェクトツリーを解決して構成できますか?自動マッパーは、登録されたすべてのオブジェクト間で失敗することなくマッピングできますか?Onionアーキテクチャの中央層は外部を参照していませんか?

これらのテストは、正確な原因を指摘することにより、構成のバグがこっそり侵入するときに多くの時間を節約できます。優れたフレームワークは、何が問題かについて非常に正確なエラーメッセージを提供します。運が良ければ、ランタイムスタックトレースの深いところに埋め込むのではなく、テストを実行するとすぐに(理想的には継続的に)エラーメッセージが表示されます。

単体テストであるかどうかはわかりませんが、おそらくメモリ内で動作し、かなり高速に実行されます。繰り返しになりますが、私にはわかりません。それは、世界的に受け入れられている単体テストの定義があったようではありません。


皮肉なことに、これは私が同僚に説明した方法とほぼ同じであり、検証(コンテナーインスタンスの1つを削除してアプリケーションを実行)を行っても、まだ値が表示されていませんでした。私は誰もが自分の意見を持っていることを理解し、私は私の声を出しました;)私は「アーキテクチャーテスト」という言葉が大好きです、私はそれを盗みます!
ChrisBint 2017

6

プログラムの要件ではなく、プログラムの内部をテストするこのようなテストの問題。プログラムが必要に応じて機能しても、テストが失敗する可能性があります。

あなたのケースでは、コンテナの設定を変更するたびに、注入を必要とする新しい依存関係がある可能性があり、テストを中断します。

さらに、追加の依存関係要件を追加したが、それをコンテナーに追加し忘れてコンテナーテストを変更した場合。すべてが成功しますが、プログラムはクラッシュします。

自動化されたより良いテストは、プログラムを起動して、クラッシュするかどうかを確認することです。

これらのタイプのエラーは、単体テストに該当する場合でも、統合またはUIテストでキャッチする必要があります。

とはいえ、コンテナ設定の複雑さが増していることは、悩みの種です。おそらく、いくつかの「悪い」テストはそれだけの価値があります。


1

ユニットテストテストコード。これ以外のすべては、「その他の」自動テストです。ここで構成をテストしているようです。環境によって設定が変わる可能性がある場合、単体テストには属していません。テストが他のテストとは異なるタイプであることを示すために、テスト属性を追加することを検討してください。


構成は静的であり、環境によって駆動されるのではなく、構成に存在するすべてのクラスがすべての環境で同じように使用されます。はい、Configであり得るインスタンスの数は、設定内のインスタンスの数、一致しなければならないテストの一部。私の例で示したように、IEnvironmentRepositoryを削除すると、他の単体テストに合格することができました。特定のコンテナテストは2つのアサートで失敗しました。1-可能なインスタンス宣言の総数が一致しませんでした。2-IEnvironmentRepositoryのインスタンスの特定の数が一致しませんでした。
ChrisBint 2017

1
コンテナーの正確さは、コーダーによって定義されます。テスト中のコードとテスト自体の両方が変更ごとに変更する必要があるという事実により、警報ベルが鳴ります。DIは目的を達成するための手段であり、それ自体が目的ではありません。Structuremap ergoなしでDIスタイルでコードを書くことは完全に可能です。これは、私の考えでは真のユニットテストではありません。もちろんコンテナは証明する必要がありますが、自動テストでそれを行うことの有効性は、ここに提供された情報が限られているため、いくぶん意味がないようです。
ロビーディー

2
単体テストのノックアップには10分かかりました。展開には1時間以上かかる場合があります。
ChrisBint 2017

1
単体テストの一部では、構成内の単一の行の存在が具体的に検証されますが、それをどのように分離することができなかったかはわかりません。私が同意できる一般的な数。
ChrisBint 2017

1
そのとき、それらにいくらかのマイレージがあるかもしれません-裁判官はあなたのために本当に呼びかけます。ただし、物理的または何らかの属性を介して分離する必要があります。
ロビーディー

0

依存関係注入コンテナの責任は、1つの動作するアプリケーションで異なるモジュールを接着することです

アプリケーションの自動テストを作成する場合、「エンドツーエンド」でテストを実行する「統合(または受け入れ)」テストがほとんどなく、アプリケーションのパイプライン全体をテストします。特定のテストケースに関連するすべてのモジュールが結合されます。正しく

したがって、依存性注入コンテナが適切に構成されていないと、これらの統合テストは失敗します。統合テストではコンテナー構成のエラーの可能性が示されるため、コンテナー自体の単体テストは役に立たなくなります。

統合テストで可能なすべてのテストケースをカバーする必要はありません。UIからデータベースまでのすべての方法をカバーする機能ごとに1つのテストケースのみです。

統合テストケースが特定の依存関係のインスタンス化をカバーしていない場合は、単にそのような依存関係を追加します。

統合テストを使用すると、構成用のユニットテストを書き直すことなく、コンテナを自由に変更できます。


0

IMO、答えは次のとおりです。

  1. それは有効な単体テストですか?ストラクチャマップが機能するのではなく、コンテナの構成をテストしています(ただし、重複が確認できます)

    • 単体テストは特定のコードをテストし、実装されたロジックをテストするために必要に応じてすべての依存関係を模擬するため、プロジェクトではなく、構造マップの有効な単体テストです。構成ロジックは構造マップ内に実装されているため、このライブラリ十分にテストし、前述のようなユニットテストを含める必要があります。さらに、このような何百ものテストを含め、実行時にいくつかの構成を動的にモックして、コンテナーは正常に動作します。
  2. そうでない場合、テストせずに構成を検証するにはどうすればよいですか。誰かが誤って必要なコード行を削除してチェックインしないようにするにはどうすればよいですか?

    • 必要な環境で構成を手動でテストできます。また、必要な特定の構成をテストするための自動化(自動テスト)を作成できます(実行時にデータをモックする必要はありません)。
  3. MyClassユニットテストは、コンテナーからIEnvironmentRepositoryのインスタンスを解決し、これを渡す必要がありますか?

    • いいえ、これは完全な単体テストです。依存関係を模擬し、MyClassロジックを独立した方法でテストするためです。

-1

UnitTestは、分離におけるユニットの望ましい動作を検証します

これは、あらゆる種類の構成UnitTestsのスコープ内にないことを意味します。

それにもかかわらず、構成には自動テストが必要ですが、これらはUnitTestsではありませ ...


単位の定義はどこで取得していますか?
ChrisBint 2017

私のようなロイOsheroveにおける単体テストの芸術:Aユニットは変更に同じ理由を持っている(生産- )コードのいずれかの塊です。私の世界では、これは通常、1つのクラスから3つまたは5つのクラスです...
ティモシートラックル2017

これはテスト中の製品コードです。
ChrisBint 2017

nitpickersの邪魔をしたいだけで、他の方法でも動作するとは思わなかった...; o)
Timothy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.