I'm under the impression this functionality exists on doctest but I wasn't able to implement it, and I'm not even sure anymore if this is possible.
I already have read a lot of references, but failed to understand correctly if that was my case or not:
- Dealing with shared libraries
- DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
- https://github.com/doctest/doctest/issues/21
- https://github.com/doctest/doctest/issues/199
- Where to put implementation when using Doctest alongside code
With that being said, here's my slim down source tree:
.
├── CMakeLists.txt
├── include
│ └── cloysterhpc
│ ├── cloyster.h
│ ├── inifile.h
│ ├── mailsystem
│ │ └── postfix.h
│ └── network.h
├── src
│ ├── CMakeLists.txt
│ ├── inifile.cpp
│ ├── mailsystem
│ │ └── postfix.cpp
│ ├── main.cpp
│ └── network.cpp
└── test
├── CMakeLists.txt
├── inifile.cpp
├── main.cpp
├── network.cpp
└── sample
└── inifile.ini
The project structure is based on this cmake_template.
What I have now working:
- I can write the tests on separate files on
./test/file.cpp. - Linking seems to be working correctly because I link the standalone test files with a static library generated from my project files.
./test/main.cppis standalone and working.
What isn't working:
- Written tests in the production code does not appear on the standalone test executable.
To achieve this here's my snippets from the files:
./CMakeLists.txt
add_subdirectory(src)
include(CTest)
add_subdirectory(test)
./src/CMakeLists.txt
# Build a library and a main binary that links to the library
add_library(cloysterhpc_object OBJECT ${SOURCE_FILES})
add_library(cloysterhpc_static STATIC $<TARGET_OBJECTS:cloysterhpc_object>)
add_executable(main main.cpp)
target_link_libraries(
main
PRIVATE
cloysterhpc_static
cloysterhpc::cloysterhpc_options
cloysterhpc::cloysterhpc_warnings)
target_link_system_libraries(
main
PRIVATE
...
doctest::doctest)
target_link_libraries(
cloysterhpc_object
PRIVATE
cloysterhpc::cloysterhpc_options
cloysterhpc::cloysterhpc_warnings)
target_link_system_libraries(
cloysterhpc_object
PRIVATE
...
doctest::doctest)
target_include_directories(cloysterhpc_object PRIVATE "${CMAKE_BINARY_DIR}/configured_files/include")
target_include_directories(cloysterhpc_object ${WARNING_GUARD} PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>)
target_include_directories(main PRIVATE "${CMAKE_BINARY_DIR}/configured_files/include")
target_include_directories(main ${WARNING_GUARD} PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>)
./test/main.cpp
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>
// This is all that is needed to compile a test-runner executable.
./test/CMakeLists.txt
file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
message(STATUS "Test files found are: ${TEST_SOURCES}")
add_executable(${PROJECT_NAME} ${TEST_SOURCES})
target_link_libraries(
${PROJECT_NAME}
PRIVATE
cloysterhpc_static
cloysterhpc::cloysterhpc_warnings
cloysterhpc::cloysterhpc_options)
target_link_system_libraries(
${PROJECT_NAME}
PRIVATE
...
doctest::doctest)
target_include_directories(${PROJECT_NAME} ${WARNING_GUARD} PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/../include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/../include>)
doctest_discover_tests(${PROJECT_NAME})
If I write any test in any .cpp file inside ./test everything works fine. But if the test is located in source file from ./src directory it will not be included in the test executable.
For the tests on ./src I've added that as following, at the end of the file:
./src/inifile.cpp
#define DOCTEST_CONFIG_IMPLEMENT
#include <doctest/doctest.h>
TEST_SUITE("Load files")
{
TEST_CASE("Get information")
{
inifile ini;
std::filesystem::path path;
path = std::filesystem::current_path() / "sample/inifile.ini";
ini.loadFile(path);
std::string clusterName = ini.getValue("information", "cluster_name");
CHECK(clusterName == "cloyster");
}
}
My goal was to be able to have:
- Tests written on production code to do unit testings.
- Support for tests on separate files to achieve a more complex scenario.
- Every test compiled to the same separate binary, on the
./testdirectory. - Keep my main function intact
- Be able to continue with a simples separate
main.cppfile for tests, that uses#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN.
I've added only snippets of the code I thought was relevant, but at this stage I'm not even sure what is relevant or not. The full code can be found on my repo if anyone if willing to look at it: https://github.com/viniciusferrao/cloysterhpc
If there's more information need please let me know, and if it isn't possible what are the possible solution to the issue?
Thanks in advance.
I was able to solve the issue recompiling every object two times. Yes I know that will increase the compilation time but it's a price that I'm willing to pay.
With that I just added the following to my
.cppfiles:So if
BUILD_TESTINGis enabled during compile time it will not enableDOCTEST_CONFIG_DISABLE.Doing that I was able to achieve what I want, that was still keep the tests on the source files while maintaining a totally separate
main.cppfile and support for additional separate test files.