I am trying to use Boost.Test (v1.69.0) with modern CMake (v3.15.0) to write and build my unit tests. The main difficulty is to split my tests in several test files: in this case Boost.Test cannot find tests.
I use the Boost distribution provided by my package manager on Linux (OpenSUSE), which means I have development headers and dynamic libraries.
Most of the documentation/tutorials/examples I found about Boost.Test/CMake interaction involves old versions of CMake (v2), and you know how much the syntax and philosophy of CMake evolved between v2 and v3. So what I found was not suited for my case.
Here is a simple MWE of my situation:
project
├── CMakeLists.txt
└── tests
├── test_one.cpp # first test file
├── test_two.cpp # second test file
└── test_unit.cpp # main test file
The main test file, which does not contain actual testing:
// 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>
The first test file, which contains actual testing:
// 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
The second test file is completely equivalent, so I will not show it. The CMake configuration:
# 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)
So, I declare the two test files as libraries and I link them statically to the main test executable.
Now, I can build this MWE, but the binary test_unit
fails to find tests and outputs:
Test setup error: test tree is empty
I do not understand why. I found two unsatisfactory ways to make it work:
I declare the two libraries dynamic, e.g. add_library(test_two SHARED tests/test_two.cpp)
.
But this makes little sense to me to use dynamic linking for something living in the same directory as the executable file.
I include the two test files in the main test file and remove the libraries in CMakeLists.txt
.
But this is ugly.
Currently, I cannot use static linking for Boost.Test, as static libraries are not provided by my package manager. I tried to use header-only Boost.Test, but the problem is the same.
What should I do?
As pointed out in the comments, each test file does not need to be a library. I actually only need the executable:
# 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)
On a side note, I can even factorize the #define BOOST_TEST_DYN_LINK
in test files with:
target_compile_definitions(test_unit PUBLIC BOOST_TEST_DYN_LINK)
So everything works.