使用 Boost.Test 和现代 CMake 的几个测试文件

Use several test files with Boost.Test and modern CMake

我正在尝试使用 Boost.Test (v1.69.0) 和现代 CMake (v3.15.0) 来编写和构建我的单元测试。 主要困难是将我的测试分成几个测试文件:在这种情况下 Boost.Test 找不到测试。

我在 Linux (OpenSUSE) 上使用我的包管理器提供的 Boost 发行版,这意味着我有开发 headers 和动态库。

我发现的关于 Boost.Test/CMake 的大部分 documentation/tutorials/examples 交互涉及旧版本的 CMake (v2),您知道 CMake 的语法和哲学在 v2 和 v3 之间演变了多少。 所以我发现的不适合我的情况。

这是我的情况的简单 MWE:

project
├── CMakeLists.txt
└── tests
    ├── test_one.cpp # first test file
    ├── test_two.cpp # second test file
    └── test_unit.cpp # main test file

主要测试文件,不包含实际测试:

// tests/test_unit.cpp
#define BOOST_TEST_MODULE "Unit Test"
#define BOOST_TEST_DYN_LINK // I use dynamic libraries of Boost
#include <boost/test/unit_test.hpp>

第一个测试文件,包含实际测试:

// tests/test_one.cpp
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(testOne)

BOOST_AUTO_TEST_CASE(testDummy) {
        BOOST_TEST(true);
}

BOOST_AUTO_TEST_SUITE_END() // testOne

第二个测试文件完全等价,就不展示了。 CMake 配置:

# CMakeLists.txt
# cmake version
cmake_minimum_required(VERSION 3.9...3.15 FATAL_ERROR)

# project definition
project(Dummy VERSION 0.0.0 LANGUAGES CXX)

# external libraries
find_package(Boost COMPONENTS unit_test_framework REQUIRED)

# first testing library
add_library(test_one tests/test_one.cpp)

# second testing library
add_library(test_two tests/test_two.cpp)

# test executable
add_executable(test_unit tests/test_unit.cpp)
target_link_libraries(test_unit Boost::unit_test_framework test_one test_two)

# testing command
enable_testing()
add_test(test_unit test_unit)

因此,我将这两个测试文件声明为库,并将它们 link 静态地添加到主要测试可执行文件中。

现在,我可以构建这个 MWE,但是二进制 test_unit 找不到测试和输出:

Test setup error: test tree is empty

我不明白为什么。 我发现了两种不太令人满意的方法来让它工作:

  1. 我声明这两个库是动态的,例如 add_library(test_two SHARED tests/test_two.cpp)。 但这对我来说对与可执行文件位于同一目录中的内容使用动态 linking 毫无意义。

  2. 我在主测试文件中包含了两个测试文件,并删除了 CMakeLists.txt 中的库。 但这很难看。

目前,我无法对 Boost.Test 使用静态 linking,因为我的包管理器不提供静态库。 我试过用header-onlyBoost.Test,问题还是一样

我该怎么办?

正如评论中所指出的,每个测试文件不需要是一个库。我实际上只需要可执行文件:

# test executable
add_executable(test_unit
    tests/test_unit.cpp
    tests/test_one.cpp
    tests/test_two.cpp
)
target_link_libraries(test_unit Boost::unit_test_framework)

附带说明一下,我什至可以分解测试文件中的 #define BOOST_TEST_DYN_LINK

target_compile_definitions(test_unit PUBLIC BOOST_TEST_DYN_LINK)

所以一切正常。