简体   繁体   中英

CMake: How to setup unit testing of a library

I work under a kata project to learn how to write unit tests in C++ ( link to the repository ). One of elements in that project is a DictionaryPath library. It's placed in a separate directory with dedicated CMakeFile.txt :

cmake_minimum_required(VERSION 3.6 FATAL_ERROR)

add_library(DictionaryPath
        include/DictionaryPath/Dictionary.h
        src/Dictionary.cpp
        include/DictionaryPath/DictionaryPath.h
        src/DictionaryPath.cpp
        src/WordsGraph.cpp
        src/WordsGraph.h
        src/DijkstraAlgorithmImpl.cpp
        src/DijkstraAlgorithmImpl.h
        src/Path.cpp
        src/Path.h
        src/Graph.h
        src/ShortestPathAlgorithm.h
        src/DijkstraAlgorithm.h)

target_include_directories(DictionaryPath PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
    PRIVATE src)

It works find with other targets (clients of the library), but when I tried to add unit tests in the same subdirectory I encountered a problem how to define a target for unit test. Eq WordsGraph class. I defined a target:

add_executable(WordsGraphTest test/WordsGraphTest.cpp)
target_link_libraries(WordsGraphTest GTest::main DictionaryPath)
add_test(NAME WordsGraphTest COMMAND WordsGraphTest)

But if I would try to refer to WordsGraph header file I have:

test/WordsGraphTest.cpp:9:10: fatal error: 'WordsGraph.h' file not found

I understand a reason - files in src/ are private, but how in this case to test library internal files without implementation for every target that links to it? Should I duplicate compilation of necessary library files in each unit test?

It should be easy to solve the problem you encountered (WordsGraph.h not found). You may use include_directories or target_include_directories.

add_library(DictionaryPath
        ...
        src/WordsGraph.h
        ...
)

target_include_directories(DictionaryPath PUBLIC
    ...
    PRIVATE src)

WordsGraph.h is in src , and you declared src as a private include directory for DictionaryPath .

If you don't want to do more than calling target_link_libraries when creating a unit test, you should either move WordsGraph.h into include , or declare src as a public or interface include directory.

If you don't want to move WordsGraph.h into include , nor declare src as a public or interface include directory, you should add a call to target_include_directories :

add_executable(WordsGraphTest test/WordsGraphTest.cpp)
target_link_libraries(WordsGraphTest GTest::main DictionaryPath)

target_include_directories(WordsGraphTest PRIVATE src)

add_test(NAME WordsGraphTest COMMAND WordsGraphTest)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM