Integrating Catch2 Unit Tests to a project which is structured with tests close to each library

111 Views Asked by At
project-root
├── build
├── cmake
├── main
│   ├── CMakeLists.txt
│   └── main.cpp
├── src
│   ├── app
│   │   ├── inc
│   │   │   └── app
│   │   │       ├── appLib.hpp
│   │   │       └── appMain.hpp
│   │   ├── src
│   │   │   ├── appLib.cpp
│   │   │   └── appMain.cpp
│   │   └── test
│   │       └── CMakeLists.txt
│       │   └── test_appLib.cpp
│   ├── common
│   │   ├── inc
│   │   │   └── common
│   │   │       └── utility.hpp
│   │   └── test
│   └── core
│       ├── inc
│       │   └── core
│       │       └── coreLib.hpp
│       ├── src
│       │   └── coreLib.cpp
│       ├── test
│       │   ├── CMakeLists.txt
│       │   └── test_coreLib.cpp
│       └── CMakeLists.txt
├── testRunner
│   ├── build
│   └── CMakeLists.txt
├── ThirdParty
└── CMakeLists.txt

I'm trying to integrate unit tests to my project, so I decided to use project structure shown above. My point is to keep test and app binaries separated, and keeping test codes close to production code, aligning with Craig Scott's recommended approach.

I'm using Catch2 as a unit test library, and it's cloned under ThirdParty dir. I can build my application binary from root/build, and tests from testRunner/build. But the problem is there is several binaries for each test directory. I want to make a single test binary for all test codes. I have to use single add_executable command in a higher level, but how to do that while using Catch2::Catch2WithMain?

root/CMakeLists.txt:

cmake_minimum_required (VERSION 3.5)

# set the build type
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif(NOT CMAKE_BUILD_TYPE)

if(CMAKE_BUILD_TYPE MATCHES Debug)
  message("Debug build.")
elseif(CMAKE_BUILD_TYPE MATCHES Release)
  message("Release build.")
endif()

set(application_name "cmake-project-template")
set(CMAKE_CXX_STANDARD 17)
set(application_version "1.0.2")
set(PROJECT_VER ${application_version})

cmake_policy(SET CMP0048 NEW)
cmake_policy(SET CMP0079 NEW)

project (${application_name} LANGUAGES C CXX)

# set search path for CMake modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
find_package(PCAP REQUIRED)
find_package(MysqlConnectorCpp REQUIRED)
add_subdirectory(ThirdParty)
add_subdirectory(src)
add_subdirectory(main)

testRunner/CMakeLists.txt:

cmake_minimum_required (VERSION 3.5)

set(application_name "TEST-cmake-project-template")
set(CMAKE_CXX_STANDARD 17)
set(application_version "1.0.2")
set(PROJECT_VER ${application_version})

cmake_policy(SET CMP0048 NEW)
cmake_policy(SET CMP0079 NEW)

project (${application_name} LANGUAGES C CXX)

# set search path for CMake modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../cmake/Modules)
find_package(PCAP REQUIRED)
find_package(MysqlConnectorCpp REQUIRED)

# Include Catch2 from ThirdParty
add_subdirectory(${CMAKE_SOURCE_DIR}/../ThirdParty/Catch2 build/Cathc2)
add_subdirectory(../ThirdParty build)

# enable testing
enable_testing()

# Add your test directories
add_subdirectory(../src/app/test app_test)
add_subdirectory(../src/core/test core_test)
add_subdirectory(../src src_test)

main/CMakeLists.txt:

set(source
    main.cpp
)

add_library(main ${source})

target_link_libraries(main PUBLIC app core)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} app core)

src/CMakeLists.txt:

add_subdirectory(app)
add_subdirectory(common)
add_subdirectory(core)

src/core/CMakeLists.txt:

set(source
    src/coreLib.cpp
)

add_library(core ${source})

target_include_directories(core PUBLIC inc)
target_include_directories(core PRIVATE inc/core)

target_include_directories(core PUBLIC ${MYSQLCONNECTORCPP_INCLUDE_DIR})

target_link_libraries(core PUBLIC
                            common
                            ${MYSQLCONNECTORCPP_LIBRARY} )

src/core/test/CMakeLists.txt:

add_executable(test_core test_coreLib.cpp)

target_include_directories(test_core PRIVATE ../inc)
target_include_directories(test_core PRIVATE ../inc/core)

# Link with the core library target
target_link_libraries(test_core PRIVATE core Catch2::Catch2WithMain)

add_test(
    NAME test_coreLib
    COMMAND test_coreLib
)

src/app/test/CMakeLists.txt:

add_executable(test_app test_appLib.cpp)

target_include_directories(test_app PRIVATE ../inc)
target_include_directories(test_app PRIVATE ../inc/core)

# Link with the app library target
target_link_libraries(test_app PRIVATE app Catch2::Catch2WithMain)

add_test(
    NAME test_app
    COMMAND test_app
)

src/core/test/test_coreLib.cpp:

#include <catch2/catch_test_macros.hpp>
#include "core/coreLib.hpp"

TEST_CASE("coreLibFoo1", "[coreLib]")
{
    coreLibClass x;
    x.coreLibfoo1();
}
0

There are 0 best solutions below