Bartvbl
Bartvbl

Reputation: 2928

How can I use Catch2 to test my CMake static library project?

I'm writing a static library which contains some shared code between several projects. In order to verify that the code in this library functions properly I'd like to use Catch2 to do some unit testing on it.

Unfortunately, when attempting to run the tests I run into the problem that the compilation's output file is a shared library (.a), rather than an executable.

I'm sure I can create a separate project which uses the functions from my static library, and subsequently run tests that way, but ideally I'd like to keep the tests and build configurations as close as possible to one another.

So my question is: what's the best way to set up my project such that I can use Catch2 for unit testing my static library code?

Here's my project's CMakeLists.txt file for reference:

project(sharedLib CXX)

find_package(OpenMP)

if (CMAKE_COMPILER_IS_GNUCC)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp -lpthread -Wall -Wextra -Wpedantic -std=c++17")
endif()

if (MSVC)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fopenmp /W4 /std:c++latest")
endif()

include_directories (
        src/
        lib/Catch2/single_include/
)

file (GLOB_RECURSE LIBRARY_SOURCES src/*.cpp
                                   src/*.c
                                   tests/*.cpp)

add_library(${PROJECT_NAME} STATIC ${LIBRARY_SOURCES})

target_include_directories(${PROJECT_NAME} PUBLIC src/)

Upvotes: 3

Views: 3028

Answers (1)

yano
yano

Reputation: 4453

A common pattern for testing static libraries is to have a separate executable which contains all the tests, and then consumes your library. for example

file (GLOB_RECURSE TEST_SOURCES tests/*.cpp)
add_executable(my_lib_tests test_main.cpp ${TEST_SOURCES})
target_link_libraries(my_lib_tests PRIVATE sharedLib)
target_include_directories(my_lib_tests PRIVATE ../path/to/secret/impl/details)

Here I also have added some include some directories to implementation details of your shared lib which you may need to test, but don't want to expose to clients via a public header.

test_main.cpp need only be:

#define CONFIG_CATCH_MAIN
#include <catch2/catch.hpp>

Then you don't have to include things in your library's build that are unrelated to the library itself, speeding up compilation time for clients, while you can work from the perspective of the test fixture

Upvotes: 2

Related Questions