2

Google テストを使用して Qt(c++) アプリケーションのテスト スーツを作成しようとしています。主な問題は、アプリケーションが 1 つのメイン プログラムとさまざまな共有ライブラリで構成されていることです。gcov/lcov (動的ライブラリでは動作しません) を使用してコード カバレッジを実行しようとするまで、すべてが正常に機能していたので、すべての .pro ファイルを変更して、次を使用して静的 lib コンパイルを行いました。


CONFIG += staticlib create_prl
QMAKE_LFLAGS += -static
LIBS += ../../Libs/lib*.a

問題は、Google テスト テスト アプリケーションが次のようなものであることです。



int main(int argc, char **argv) {

  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

したがって、実行時にリンケージを検出します。つまり、ここでテストアプリケーションをコンパイルすると、警告や問題を示すものは何も表示されず、テストアプリケーションを実行すると、何も見つからないため 0 テストが実行されます。

私の解決策(迷惑なものをやめる)は、偽のパブリック静的メンバーのテストに使用される各クラスで定義し、その上でメインのテストアプリケーションの操作を行うことです:


class SETTINGS_TESTS_SHARED_EXPORT SettingsTests: public testing::Test {

public:
 SettingsTests();
 virtual ~SettingsTests();

 static bool dummy;
protected:
 virtual void SetUp();
 virtual void TearDown();

private:
 Settings* _setting0;
 Settings* _setting1;
 Settings* _setting2;
};



using namespace MBI::SETTINGS;
using namespace MBI::TESTS;

int main(int argc, char **argv) {

  SettingsTests::dummy = true;
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

そのため、アプリケーションでそのライブラリのリンクを強制できます。

また、gcc でそのようなことを行うオプション -u を見つけましたが、機能していないようです。コンパイル時にシンボルが検出されない場合、静的ライブラリのリンクを強制する方法を誰かが持っていますか?

4

2 に答える 2

0

私は質問を完全には理解していません。実際に何::testing::InitGoogleTestをしているのRUN_ALL_TESTSか、動的リンクとどのように関連しているのかについては説明されていません。

--unresolved-symbols=ignore-allただし、オプション を使用するか、オプションを gcc に渡す必要がある場合は、GNU リンカがリンク時に未解決のシンボルを無視するようにすることができます-Wl,--unresolved-symbols=ignore-all

于 2009-11-23T22:46:10.470 に答える
0

Google テスト ドキュメントには、Visual C++ DLL とのリンケージの問題についての言及があります。

Visual C++ ユーザー向けの重要な注意事項

テストをライブラリに配置し、main() 関数が別のライブラリまたは .exe ファイルにある場合、それらのテストは実行されません。その理由は、Visual C++ のバグです。テストを定義すると、Google Test は特定の静的オブジェクトを作成して登録します。これらのオブジェクトは他の場所から参照されませんが、それらのコンストラクターは引き続き実行されるはずです。Visual C++ リンカーは、ライブラリ内の何も他の場所から参照されていないことを確認すると、ライブラリをスローします。リンカーがライブラリを破棄しないようにするには、メイン プログラムからのテストでライブラリを参照する必要があります。方法は次のとおりです。ライブラリ コードのどこかで関数を宣言します。

__declspec(dllimport) int PullInMyLibrary() { return 0; }
テストをスタティック ライブラリ (DLL ではない) に配置する場合、__declspec(dllexport) は必要ありません。次に、メイン プログラムで、その関数を呼び出すコードを記述します。

int PullInMyLibrary();
静的 int ダミー = PullInMyLibrary();
これにより、テストが参照されたままになり、起動時にテストが登録されます。

さらに、スタティック ライブラリでテストを定義する場合は、メイン プログラムのリンカー オプションに /OPT:NOREF を追加します。MSVC++ IDE を使用している場合は、.exe プロジェクトのプロパティ/構成プロパティ/リンカー/最適化に移動し、参照設定を参照されていないデータを保持する (/OPT:NOREF) に設定します。これにより、Visual C++ リンカーは、テストによって生成された個々のシンボルを最終的な実行可能ファイルから破棄しなくなります。

ただし、もう 1 つ落とし穴があります。Google Test を静的ライブラリ (gtest.vcproj で定義されている方法) として使用する場合、テストも静的ライブラリに存在する必要があります。それらを DLL に含める必要がある場合は、Google Test も DLL にビルドするように変更する必要があります。そうしないと、テストが正しく実行されないか、まったく実行されません。ここでの一般的な結論は次のとおりです。生活を楽にしましょう - ライブラリにテストを書かないでください!

そして、採用された解決策は、私が g++ で行ったこととほとんど同じです。qmake が中間ファイル moc_* を生成し、私のコードがそれに対してリンクされているという事実を疑っています。

于 2009-11-24T08:00:42.247 に答える