将 Googletest 添加到现有的 CMake 项目

Fre*_*per 5 cmake googletest c++14

我无法将 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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

existing_source/existing.h

#ifndef TESTTESTER_EXISTING_H
#define TESTTESTER_EXISTING_H

int sample() {
    return 1;
}

#endif //TESTTESTER_EXISTING_H
Run Code Online (Sandbox Code Playgroud)

existing_source/main.cpp

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

int main() {
    std::cout << "sample() output = " << sample() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

目标:

使用 CMake 构建将创建两个可执行文件,一个是TestTester,另一个是Test_TestTester(对不起,名字有点奇怪,看起来我可以选择一个更好的项目名称!)。

TestTester将是主要的项目可执行文件,它将运行来自existing_course/main.cpp和 output的代码sample() output = 1

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

尝试:

我尝试使用 CMake 的add_subdirectory()在 test 子目录中公开第二个 CMakeLists.txt,该子目录有自己的add_executable()和测试程序的名称,但是我找不到任何与测试程序相关的输出。使用enable_testing()后跟add_test()也无法产生任何更改。

更新:

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

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

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

Mik*_*han 9

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

您似乎错误地认为:

add_test(NAME Test COMMAND Test_TestTester)
Run Code Online (Sandbox Code Playgroud)

在你的new_test_source/CMakeLists.txt就是让你的Test_TestTester 执行由make.

事实上,正如宣布的第一行add_test文件

将测试添加到要由 ctest(1) 运行的项目。

当您在子项目的构建目录中运行之后,您的add_test命令才足以Test_TestTester运行。makectestTest_TestTester

此外,即使这只会在您ctest通过调用enable_testing()in启用该子项目的测试时发生new_test_source/CMakeLists.txt,而您没有。你说你后来这样做了:

使用 enable_testing() 后跟 add_test() 也无法产生任何更改。

但那是因为您仍然没有做任何事情,只是创建了可以运行的 测试ctest仍然没有运行ctest.

因此,假设我在我的工作目录(我有)中有您的样本项目,并且我刚刚new_test_source/CMakeLists.txt通过更改进行了更改:

project(Test_TestTester)
Run Code Online (Sandbox Code Playgroud)

到:

project(Test_TestTester)
enable_testing()
Run Code Online (Sandbox Code Playgroud)

然后:

$ mkdir build
$ cd build
$ cmake ..
Run Code Online (Sandbox Code Playgroud)

生成构建系统,并且:

$ 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
Run Code Online (Sandbox Code Playgroud)

构建一切,并且:

# 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
Run Code Online (Sandbox Code Playgroud)

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

$ 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
Run Code Online (Sandbox Code Playgroud)

如果您想在运行时在控制台上看到所有内容,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
)
Run Code Online (Sandbox Code Playgroud)

new_test_source/CMakeLists.txt。然后一个干净的输出make是:

$ 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
Run Code Online (Sandbox Code Playgroud)