CMake:如何设置库的单元测试

时间:2016-10-04 23:26:49

标签: c++ unit-testing cmake tdd googletest

我在kata项目下工作,学习如何用C ++编写单元测试(link to the repository)。该项目中的一个元素是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)

它可以找到其他目标(库的客户端),但是当我尝试在同一个子目录中添加单元测试时,我遇到了如何为单元测试定义目标的问题。 E.q. WordsGraph课程。我定义了一个目标:

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/中的文件是私有的,但在这种情况下如何测试库内部文件而不实现链接到它的每个目标?我应该在每个单元测试中复制必要库文件的编译吗?

2 个答案:

答案 0 :(得分:2)

解决您遇到的问题应该很容易(找不到WordsGraph.h)。您可以使用include_directories或target_include_directories。

答案 1 :(得分: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,或将src声明为WordsGraph.h public或interface include目录。

如果您不想将include移至src,也不要将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) 的调用:

var customers = (from e in docss.Descendants("data").Elements("customer")
                         where (bool)e.Element("pirmaryCustCheck") == true
                         select new 
                         {
                             Name = (string)e.Element("custName"),
                             Id = (string)e.Element("id"),
                         }).ToList();