我正在尝试将单元测试集成到 native (C++)gradle 项目中,但我似乎找不到可行的解决方案。链接测试可执行文件时会出现问题,因为有两个可用的 wmain(一个用于主应用程序,一个用于单元测试)。有谁知道如何在链接步骤中排除其中之一?
这是我的设置的一个最小示例:
项目结构
build.gradle
src
-> main
-> cpp
-> main.cpp
-> registry.cpp
-> headers
-> registry.hpp
-> test
-> cpp
-> main_test.cpp
-> test_registry.cpp
libs
-> googletest
-> 1.7.0
-> include
-> ...
-> lib
-> libgtest.a
build.gradle
apply plugin: 'cpp'
apply plugin: 'google-test-test-suite'
model {
platforms {
x86 {
architecture "x86"
}
x64 {
architecture "x86_64"
}
}
components {
main(NativeExecutableSpec) {
baseName "Registry"
targetPlatform "x86"
binaries.all {
cppCompiler.args "-std=c++11", "-municode", "-mwindows"
linker.args "-municode", "-mwindows"
}
}
}
testSuites {
mainTest(GoogleTestTestSuiteSpec) {
testing $.components.main
sources {
cpp.source.srcDir 'src/test/cpp'
}
}
}
repositories {
libs(PrebuiltLibraries) {
googleTest {
headers.srcDir "libs/googletest/1.7.0/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile =
file("libs/googletest/1.7.0/lib/libgtest.a")
}
}
}
}
}
model {
binaries {
withType(GoogleTestTestSuiteBinarySpec) {
lib library: "googleTest", linkage: "static"
cppCompiler.args "-std=c++11", "-municode"
linker.args "-municode"
}
}
}
错误消息
:compileMainExecutableMainCpp
:linkMainExecutable
:mainExecutable
:assemble
:compileMainTestGoogleTestExeMainCpp
:compileMainTestGoogleTestExeMainTestCpp
:linkMainTestGoogleTestExe
C:\Users\minimal\build\objs\mainTest\mainCpp\e7f4uxujatdodel7e7qw5uhsp\main.obj:main.cpp:(.text+0x0): multiple definition of `wmain'
C:\Users\minimal\build\objs\mainTest\mainTestCpp\271ezc0ay5ubap2l962cnectq\main_test.obj:main_test.cpp:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
:linkMainTestGoogleTestExe FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':linkMainTestGoogleTestExe'.
> A build operation failed.
Linker failed while linking mainTest.exe.
选项.txt
-o
C:\\Users\\minimal\\build\\exe\\mainTest\\mainTest.exe
C:\\Users\\minimal\\build\\objs\\mainTest\\mainTestCpp\\271ezc0ay5ubap2l962cnectq\\main_test.obj
C:\\Users\\minimal\\build\\objs\\mainTest\\mainTestCpp\\dp6ieaohq04qqqa31sdfwrsxj\\test_registry.obj
C:\\Users\\minimal\\build\\objs\\mainTest\\mainCpp\\68sxcjmhakj69ha7wqtijofs3\\Registry.obj
C:\\Users\\minimal\\build\\objs\\mainTest\\mainCpp\\e7f4uxujatdodel7e7qw5uhsp\\main.obj
C:\\Users\\minimal\\libs\\googletest\`.7.0\\lib\\libgtest.a
-municode
-m32
非常感谢任何帮助!
最佳答案
您的问题是由于尝试使用 googletest 做错误的事情而产生的。
Googletest 是一个单元测试框架。这意味着它是为了测试
库 - 其中库在这里表示一堆函数和/或类
不包含 main
函数。它不是用于测试应用程序,
具有 main
功能。您可以通过运行以下命令来测试应用程序
应用并进行受控(可能是自动化)观察
其公开的行为。这种测试有多种名称,但都是
不是单元测试,单元测试是第一位的。
要使用 googletest 测试库,您需要创建一个应用程序
运行你的 googletest 测试用例。该应用程序(测试运行程序)需要
它自己的 main
函数,除了运行测试用例之外什么也不做:
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
某人拥有一个包含以下内容的应用程序是很常见的 一堆特定于应用程序的函数和/或类 喜欢用 googletest 进行单元测试。这样做的方法是:-
将应用程序重构为:
- 一个库 - 称之为应用程序库 - 包含您想要的函数和/或类
单元测试,不包括
main
函数。 - 其余部分,包括
main
函数。
- 一个库 - 称之为应用程序库 - 包含您想要的函数和/或类
单元测试,不包括
通过将其余部分与应用程序库链接来构建应用程序。
创建一个测试运行应用程序,其中包含您的 googletest 测试用例 和 googletest
main
函数。当然,测试用例,#include
应用程序库的标题。通过将测试用例和主函数与应用程序库链接来构建测试运行程序。
通过运行测试运行程序对应用库进行单元测试。
最简单、最快的方法就是将所有应用程序,
除了 main
函数之外,都进入应用程序库。但这可能更明智
仅在开发时将内容从应用程序移至应用程序库
单元测试来覆盖它,这样你就可以随时知道应用程序库中的内容
有单元测试,其余没有。以此类推,直到除了
main
函数位于应用程序库中,并且具有单元测试。
你几乎肯定会发现分解应用程序库的过程 这样您就可以将其与应用程序和测试运行器公开 应用程序中的设计缺陷并迫使您做得更好。这可以启动一个 应用程序库正在走向成熟,成为一个多应用程序库,一个稳定的高质量 软件 Assets 。
因此,您从一个项目(应用程序项目)开始,最终得到 三个项目:
- 构建应用库的项目
- 构建应用程序的项目
- 构建测试运行程序的项目
无论怎样,您拥有的任何构建系统都将允许您自动进行 这些项目之间的依赖关系。显然,您想要:
- 构建应用程序需要构建应用程序库
- 构建测试运行程序需要构建应用程序库
但是您可以更进一步,使构建应用程序需要 构建测试运行程序 - 它将构建应用程序库 - 并成功 运行测试运行程序。这样,您将永远不会构建应用程序 除非单元测试成功。这对你来说可能有点过分了 桌面开发周期,但不适用于 CI 构建。
对于下一个应用程序,您可以从这个 3 项目模式开始, 仅当您可以从应用程序获取功能时才向应用程序添加功能 应用程序库,必须由单元测试覆盖,并且必须通过 在测试运行程序中。那么你就以正确的方式使用 googletest 了。
关于c++ - 如何在将测试 exe 与 gradle 链接时排除第二个主程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42713190/