我正在尝试使用谷歌测试为我的Qt(c ++)应用程序编写测试套件,主要问题是我的应用程序包含一个主程序和各种共享库。一切都运行得很好,直到我尝试使用gcov / lcov(不在动态库上运行)进行一些代码覆盖,所以我修改了所有.pro文件以使用静态lib编译:
CONFIG += staticlib create_prl
QMAKE_LFLAGS += -static
LIBS += ../../Libs/lib*.a
问题是谷歌测试测试应用程序是这样的:
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
因此它在运行时检测到链接,这意味着当我在这里编译测试应用程序时没有警告或任何表明存在问题的情况,并且在运行测试应用程序时它执行0测试,因为它没有找到任何。< / p>
我的解决方案(退出烦人的方法)是在每个类中定义将用于测试虚假公共静态成员并对其执行主测试应用程序的操作:
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();
}
所以我可以在我的应用程序上强制连接该lib。
我还发现选项-u在gcc中执行类似的操作,但似乎不起作用。如果在编译时没有检测到符号,有没有办法强制静态库链接?
答案 0 :(得分:0)
我不完全理解这个问题,但没有解释::testing::InitGoogleTest
和RUN_ALL_TESTS
实际上做了什么,以及它们与动态链接的关系。
但是:您可以使用选项--unresolved-symbols=ignore-all
使GNU链接器在链接时忽略未解析的符号,或者如果您需要将选项传递给gcc,-Wl,--unresolved-symbols=ignore-all
。
答案 1 :(得分:0)
在google测试文档中,提到了visual c ++ dll的链接问题:
Important note for Visual C++ users If you put your tests into a library and your main() function is in a different library or in your .exe file, those tests will not run. The reason is a bug in Visual C++. When you define your tests, Google Test creates certain static objects to register them. These objects are not referenced from elsewhere but their constructors are still supposed to run. When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out. You have to reference your library with tests from your main program to keep the linker from discarding it. Here is how to do it. Somewhere in your library code declare a function: __declspec(dllimport) int PullInMyLibrary() { return 0; } If you put your tests in a static library (not DLL) then __declspec(dllexport) is not required. Now, in your main program, write a code that invokes that function: int PullInMyLibrary(); static int dummy = PullInMyLibrary(); This will keep your tests referenced and will make them register themselves at startup. In addition, if you define your tests in a static library, add /OPT:NOREF to your main program linker options. If you use MSVC++ IDE, go to your .exe project properties/Configuration Properties/Linker/Optimization and set References setting to Keep Unreferenced Data (/OPT:NOREF). This will keep Visual C++ linker from discarding individual symbols generated by your tests from the final executable. There is one more pitfall, though. If you use Google Test as a static library (that's how it is defined in gtest.vcproj) your tests must also reside in a static library. If you have to have them in a DLL, you must change Google Test to build into a DLL as well. Otherwise your tests will not run correctly or will not run at all. The general conclusion here is: make your life easier - do not write your tests in libraries!
采用的解决方案几乎就是我用g ++做的。我怀疑qmake生成中间文件moc_ *并且我的代码与之相关联。