CMake: как настроить модульное тестирование библиотеки

#c #unit-testing #cmake #tdd #googletest

#c #модульное тестирование #cmake #tdd #googletest

Вопрос:

Я работаю над проектом kata, чтобы научиться писать модульные тесты на C (ссылка на репозиторий). Одним из элементов этого проекта является библиотека DictionaryPath. Он помещается в отдельный каталог с выделенным 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)
  

Он работает с другими целями (клиентами библиотеки), но когда я попытался добавить модульные тесты в тот же подкаталог, я столкнулся с проблемой, как определить цель для модульного тестирования. Например.q. WordsGraph class . Я определил цель:

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

Но если я попытаюсь обратиться к WordsGraph заголовочному файлу, у меня есть:

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

Я понимаю причину — файлы в src/ являются частными, но как в этом случае протестировать внутренние файлы библиотеки без реализации для каждой цели, которая ссылается на нее? Должен ли я дублировать компиляцию необходимых файлов библиотеки в каждом модульном тестировании?

Ответ №1:

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

target_include_directories(DictionaryPath PUBLIC
    ...
    PRIVATE src)
  

WordsGraph.h находится в src , и вы объявили src его как частный каталог для включения DictionaryPath .

Если вы не хотите делать ничего, кроме вызова target_link_libraries при создании модульного теста, вам следует либо перейти WordsGraph.h в include каталог public или interface include, либо объявить src его как каталог public или interface include.

Если вы не хотите переходить WordsGraph.h в include src каталог public или interface include или объявлять его общедоступным, вам следует добавить вызов 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)
  

Ответ №2:

Должно быть легко решить проблему, с которой вы столкнулись (WordsGraph.h не найден). Вы можете использовать include_directories или target_include_directories .