将Googletest添加到现有的CMake项目中

6

我在将googletest集成到我的现有项目中遇到了麻烦。我创建了一个简单的项目来表示我的项目结构:

项目结构

项目结构图像(无法直接发布,需要10点声望)

CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(TestTester)
set(CMAKE_CXX_STANDARD 14)

include_directories(existing_source)
add_subdirectory(existing_source)
add_subdirectory(new_test_source)

existing_source/CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(Test_TestTester)
set(CMAKE_CXX_STANDARD 14)

add_executable(TestTester main.cpp existing.h)

new_test_source/CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(Test_TestTester)
set(CMAKE_CXX_STANDARD 14)

find_package(PkgConfig REQUIRED)
pkg_check_modules(gtest REQUIRED gtest>=1.8.1)

SET(CMAKE_CXX_FLAGS -pthread)
enable_testing()

include_directories(${gtest_INCLUDE_DIRS})

add_executable(Test_TestTester main_test.cpp ../existing_source/existing.h)
target_link_libraries(Test_TestTester ${gtest_LIBRARIES})
add_test(NAME Test COMMAND Test_TestTester)

existing_source/existing.h

#ifndef TESTTESTER_EXISTING_H
#define TESTTESTER_EXISTING_H

int sample() {
    return 1;
}

#endif //TESTTESTER_EXISTING_H

existing_source/main.cpp

#include <iostream>
#include "existing.h"

int main() {
    std::cout << "sample() output = " << sample() << std::endl;
    return 0;
}

new_test_source/main_test.cpp

#include <gtest/gtest.h>
#include "../existing_source/existing.h"

TEST(SampleTestCase, TestOneIsOne) {
    EXPECT_EQ(1, 1);
}

TEST(ExistingCodeTestCase, TestSample) {
    EXPECT_EQ(1, sample());
}


GTEST_API_ int main(int argc, char **argv) {
    printf("Running main() from %s\n", __FILE__);
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

目标:

使用CMake构建将创建两个可执行文件,一个是TestTester,另一个名为Test_TestTester(很抱歉,这个名称看起来我本可以选择更好的项目名称!)。

TestTester将是主项目可执行文件,它将运行existing_course/main.cpp中的代码,并输出sample() output = 1

Test_TestTester应该是来自main_test.cpp的单元测试,测试1 == 11 == sample()。这应该在构建项目时运行。

尝试:

我尝试使用CMake的add_subdirectory()公开test子目录中具有其自己的add_executable()的第二个CMakeLists.txt,其中包含测试程序的名称,但我找不到与测试程序相关的任何输出。使用enable_testing()后跟add_test()也未能产生任何变化。

更新:

我意识到一些问题和假设是错误的。

  • 在CLion中,默认情况下要构建特定目标。必须调用Build all (cmake --build ... --target all)来构建其他可执行文件。
  • 我阅读的其他问题似乎与此不相关。在将其包含到项目中之前,我在计算机上编译并安装了googletest。
  • 这可能不是一个问题,但看起来大多数人选择使用每个目录都有自己的CMakeLists.txt文件来组织他们的项目。我重新组织了我的项目以匹配,以便更容易遵循其他人的建议。

我用我的更改更新了CMakeLists文件。使用--target all可以适当地构建所有内容,但我仍然无法在构建项目时运行测试。


让测试运行是什么意思?怎么做?有错误信息吗?你尝试了什么?你如何运行它们?测试可执行文件是否构建正确?如果单独运行测试可执行文件会发生什么?为什么在.h文件中提供具有外部链接的符号定义?sample函数不应该至少有staticstatic inline吗? - KamilCuk
测试通过执行Test_TestTester可执行文件运行。如果我没有表达清楚,抱歉,我的意思是在构建过程中集成测试的执行是目前的难点。add_test()的COMMAND部分是告诉CMake要执行什么命令来运行测试,对吗?静态或内联说明符可能更正确,但这只是一个有效的最小示例。 - Fred Cooper
1个回答

10

你发布的样本项目几乎没有问题。

看起来你错误地假设:

add_test(NAME Test COMMAND Test_TestTester)

在你的new_test_source/CMakeLists.txt中只需要添加一行代码即可使Test_TestTestermake后得以执行。
实际上,正如add_test文档的第一行所声明的那样:
“向项目添加一个测试,由ctest(1)运行。”
你的add_test命令只足以在make后运行Test_TestTester, 当你在Test_TestTester子项目的构建目录下运行ctest时。
此外,仅在你通过在new_test_source/CMakeLists.txt中调用enable_testing()启用了该子项目的ctest 测试之后才会发生这种情况,而你没有这样做。你说你后来做到了:
“使用enable_testing()后跟add_test()也未能产生任何变化。”
但是这还只是创建了你可以使用ctest运行的测试,并且你仍然没有运行ctest
因此,假设我已经将你的样本项目放在我的工作目录中(我已经这样做了), 并且我刚刚通过更改new_test_source/CMakeLists.txt中的内容进行了更改:
project(Test_TestTester)

to:

project(Test_TestTester)
enable_testing()

然后:

$ mkdir build
$ cd build
$ cmake ..

生成构建系统,并:

$ make
Scanning dependencies of target TestTester
[ 25%] Building CXX object existing_source/CMakeFiles/TestTester.dir/main.cpp.o
[ 50%] Linking CXX executable TestTester
[ 50%] Built target TestTester
Scanning dependencies of target Test_TestTester
[ 75%] Building CXX object new_test_source/CMakeFiles/Test_TestTester.dir/main_test.cpp.o
[100%] Linking CXX executable Test_TestTester
[100%] Built target Test_TestTester

构建所有内容,并且:

# We're still in `./build`
$ cd new_test_source/
$ ctest
Test project /home/imk/develop/so/scrap2/build/new_test_source
    Start 1: Test
1/1 Test #1: Test .............................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.00 sec

运行你的测试。完整的测试日志保存在:

$ cat ./Testing/Temporary/LastTest.log
Start testing: Feb 12 19:23 GMT
----------------------------------------------------------
1/1 Testing: Test
1/1 Test: Test
Command: "/home/imk/develop/so/scrap2/build/new_test_source/Test_TestTester"
Directory: /home/imk/develop/so/scrap2/build/new_test_source
"Test" start time: Feb 12 19:23 GMT
Output:
----------------------------------------------------------
Running main() from /home/imk/develop/so/scrap2/new_test_source/main_test.cpp
[==========] Running 2 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 1 test from SampleTestCase
[ RUN      ] SampleTestCase.TestOneIsOne
[       OK ] SampleTestCase.TestOneIsOne (0 ms)
[----------] 1 test from SampleTestCase (0 ms total)

[----------] 1 test from ExistingCodeTestCase
[ RUN      ] ExistingCodeTestCase.TestSample
[       OK ] ExistingCodeTestCase.TestSample (0 ms)
[----------] 1 test from ExistingCodeTestCase (0 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 2 test suites ran. (0 ms total)
[  PASSED  ] 2 tests.
<end of output>
Test time =   0.00 sec
----------------------------------------------------------
Test Passed.
"Test" end time: Feb 12 19:23 GMT
"Test" time elapsed: 00:00:00
----------------------------------------------------------

End testing: Feb 12 19:23 GMT

如果你希望在运行ctest时在控制台上看到所有内容,可以以详细模式运行ctest -V。或者,如果你只想在测试失败时查看细节,可以运行ctest --output-on-failure
一切都按照预期工作,也许你对此很满意,知道它是如何工作的。如果你仍然希望你的测试能够被make自动运行-这不是传统的做法-那么你需要向Test_TestTester目标添加一个自定义的后构建命令来自动运行ctest。只需附加,例如:
add_custom_command(TARGET Test_TestTester
                   COMMENT "Run tests"
                   POST_BUILD COMMAND ctest ARGS --output-on-failure
)

new_test_source/CMakeLists.txt 添加进去。然后执行 make clean 命令,输出如下:

$ make
Scanning dependencies of target TestTester
[ 25%] Building CXX object existing_source/CMakeFiles/TestTester.dir/main.cpp.o
[ 50%] Linking CXX executable TestTester
[ 50%] Built target TestTester
Scanning dependencies of target Test_TestTester
[ 75%] Building CXX object new_test_source/CMakeFiles/Test_TestTester.dir/main_test.cpp.o
[100%] Linking CXX executable Test_TestTester
Run tests
Test project /home/imk/develop/so/scrap2/build/new_test_source
    Start 1: Test
1/1 Test #1: Test .............................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.00 sec
[100%] Built target Test_TestTester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接