3

ATL 経由でコンポーネントを公開するプロジェクトを引き継いでいます。

このセットアップでカバーする単体テストの主な領域は 2 つあります。

  • 内部コンポーネントのテスト (COM 経由で公開される場合と公開されない場合があります)
  • 外部に公開されたコンポーネントのテスト (別名、公開されたインターフェースのテスト)

現在、プロジェクトには、すべての内部コンポーネントの単体テストがソリューション内にあります。これらは、実行時にコンパイルして実行するプリプロセッサ フラグによって有効になります。

私が行ってきた調査から、「標準」は、単体テストを別のサブプロジェクトに配置し、単体テストが内部コンポーネントにアクセスするための主要なソリューション供給フックを持つことであるようです。このセットアップでは、単体テスト ソリューションは、テスト対象のソリューションへの依存関係を設定します。これは本当に「規範」なのか、それとも単体テスト フレームワークをテスト対象のソリューション内に配置する人がたくさんいるのでしょうか (別名、単体テストはサブ プロジェクトではなく#ifdef、プリプロセッサ フラグが指定されていない)?

現在使用されている単体テスト フレームワークは cppunit のようで、gtest に切り替えて、すべてを別のサブ プロジェクトに移動しようと考えていましたが、長期的にはその努力が価値があることを確認したいと考えています。

私が考えた 1 つの方法は__declspec、クラスをテストすることでした。クラスは、プリプロセッサの定義が指定されている場合にのみ公開されます。次に、別の単体テスト サブプロジェクトにより、そのプリプロセッサがメイン ソリューションにインナーを公開するように指示できるようになります。これが最善のルートかどうかはわかりません。

だから私の質問は:

  1. 単体テストを別の(サブ)プロジェクトに配置し、テストされるソースからコンポーネントを公開するのは標準ですか(フックを介して、クラス定義を公開するなど)?
  2. COM DLL から内部コンポーネントを公開する最良の方法は何ですか?
  3. 内部コンポーネントのテストを可能にするプリプロセッサ フラグ__declspecは悪い考えでしょうか? テスト対象の項目が通常の操作中に通常は公開されない単体テストで、他の誰かがこれを行ったことがありますか?

コメントありがとうございます!

4

3 に答える 3

4

別のチームの誰かが、彼らのチームはすべての単体テストを別々のプロジェクトに配置し、静的ライブラリを介して内部を公開できたと言いました。これは、モジュール性に役立ち、他の多くの利点を提供するという点で、私にとって非常に理にかなっています。したがって、コードの主要な結合はそれぞれ静的ライブラリになり(過度に行き過ぎることはありません;))、静的ライブラリごとに個別の単体テストソリューションが必要になります。次に、メイン DLL は、必要なアイテムを公開するシン ラッパーになります。

したがって、ソリューションは次のようになります。

メインソリューション

  • ProjCommonLib
  • ProjExportsLib
  • ProjImportsLib
  • ProjOtherStuffLib
  • COMDLL-プロジェクト
  • UnitTestsFolder
    • ProjCommonLibTests
    • ProjExportsLibTests
    • ProjImportsLibTests
    • ProjOtherStuffLibTests
    • COMDLL-ProjTests

このタイプのセットアップにより、単体テストは静的ライブラリに依存関係を設定し、__declspec を処理することなく内部に完全にアクセスできます。他のライブラリは静的ライブラリであるため、DLL にはモジュール性によるパフォーマンスの影響がないため、これはかなりクリーンに見えます。

これを「回答」として配置して、賛成票が得られるかどうかを確認します(別名、「この回答は良いアプローチであり、私もそうしています」)。これが悪い解決策である場合は、回答を投稿してください。

于 2011-09-13T13:32:59.837 に答える
1

テストを既存のプロジェクトに埋め込むか、新しいプロジェクトを作成するかは、自由に選択できると思います。新しいプロジェクトを作成する必要がないことを意味するため、cppunit テストでは前者のアプローチを選択しますが、C# プロジェクトでは、別のプロジェクトを作成して維持するという単調な作業を行う Visual Studio の単体テスト フレームワークを使用します。

'ed ブロックが再コンパイルされないという問題が発生したことは一度もありません#ifdef。依存関係のチェックにより、それが確認されます (別の dll でそれらを公開し、エクスポートを使用した場合、これは問題になります。

cppunitかなりの年数使用しており、最近使用したばかりgtestです。gtest は非常に豊富な機能を備えていますが、かなりの数の構造上の違いがあるため、移植するのは非常に困難です。既存のテストが cppunit にある場合は、それを続行することをお勧めします。

(私が見つけた限りでは) gtest でサポートされていない cppunit について私が気に入っていることの 1 つは、フィクスチャ内の最初の失敗によりフィクスチャが失敗するため、次のように実行できることです。

CPPUNIT_ASSERT(pointer!=NULL);
CPPUNIT_ASSERT(pointer->deferenceIt());  // if the pointer was null it would have returned above

gtest はこのインスタンスで引き続き実行され、2 行目でクラッシュします。cppunit テストがこの動作に依存している場合、移植がさらに難しくなります。

于 2011-09-12T21:41:24.310 に答える
0

ブロックを使用し#ifdefても再コンパイルがトリガーされない可能性があるため、単体テストを別のプロジェクトに配置する方が良いオプションだと思います。

于 2011-09-12T15:36:30.737 に答える