【问题标题】:Catch2 unit tests are not running with CMake projectCatch2 单元测试未与 CMake 项目一起运行
【发布时间】:2020-01-16 13:04:29
【问题描述】:

我的项目结构如下:

|--assets/
|--core/
    |--deps/
        |--Catch2/
             |--win32/
                  |--# Have Catch2 library installed here
    |--include/
         |--# Nothing here
    |--src/
        |--sample.cpp # No content in this file
    |--tests/
         |--test.cpp
    |--CMakeLists.txt
|--main.cpp
|--CMakeLists.txt

顶层 CMakeLists.txt 内容为:

cmake_minimum_required (VERSION 3.8)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
project("My.Project")

add_executable(MyProject main.cpp)

# Copy all DLLs if windows:
if(WIN32)
    file(GLOB_RECURSE DYNAMIC_LIBS "${CMAKE_CURRENT_SOURCE_DIR}/*.dll")
    foreach(dll ${DYNAMIC_LIBS})
        add_custom_command(TARGET AZTEC_EDITOR POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy
            ${dll} $<TARGET_FILE_DIR:AZTEC_EDITOR>)
    endforeach()
else(APPLE)
endif()

add_subdirectory(core)
target_link_libraries(MyProject MyLib)

“core”文件夹中的CMakeLists.txt文件为:

file(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
file(GLOB TEST_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp")

add_library(MyLib ${HEADER_FILES} ${SOURCE_FILES} ${TEST_FILES})

target_include_directories(MyLib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")

# Copy all DLLs if windows:
if(WIN32)
    file(GLOB_RECURSE DYNAMIC_LIBS "${CMAKE_CURRENT_SOURCE_DIR}/*.dll")
    foreach(dll ${DYNAMIC_LIBS})
        add_custom_command(TARGET AZTEC_EDITOR_CORE POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy
            ${dll} $<TARGET_FILE_DIR:AZTEC_EDITOR_CORE>)
    endforeach()
else(APPLE)
endif()

# Catch2 stuff:
if(WIN32)
    find_package(Catch2 REQUIRED PATHS "${CMAKE_CURRENT_SOURCE_DIR}/deps/catch2/win32")
    target_link_libraries(MyLib Catch2::Catch2)
endif()

include(CTest)
include(Catch)
catch_discover_tests(MyLib)

我的test.cpp 内容(来自 Catch2 文档,此测试应该失败):

#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"

unsigned int Factorial(unsigned int number)
{
    return number <= 1 ? number : Factorial(number - 1)*number;
}

TEST_CASE("Factorials are computed", "[factorial]")
{
    REQUIRE(Factorial(1) == 2); // Should fail here.
    REQUIRE(Factorial(2) == 2);
    REQUIRE(Factorial(3) == 6);
    REQUIRE(Factorial(10) == 3628800);
}

当我使用@ 987654329生成Visual Studio文件@时,通常,当发现测试时,我会看到一个项目在“cmakepredefinedtargets”下调用“run_tests”下分组。但是,我再也看不到这个项目了。

另外,当我构建项目(使用 Visual Studio 2017)时,测试没有运行。请帮忙。谢谢。

【问题讨论】:

  • 尝试在根CMakeLists.txt (cmake.org/cmake/help/latest/command/enable_testing.html) 中添加enable_testing()
  • @StephenNewell 成功了 :D 现在我可以看到 RUN_TESTS 项目了。有一件事(我认为这与 Catch2 本身有关,但可能你能帮忙吗?)。虽然 RUN_TESTS 现在可用,但当我构建它时,它实际上表示没有发现任何测试。我不得不将“核心”中的 CMakeLists.txt 从add_library(MyLib ${HEADER_FILES} ${SOURCE_FILES} ${TEST_FILES}) 更改为add_executable(MyLib ${HEADER_FILES} ${SOURCE_FILES} ${TEST_FILES})。知道如何保留add_library() 吗?否则,也许你可以发表评论作为ans,所以我可以接受。谢谢。
  • @swdon:测试是你可以运行的东西。一个人可能会运行一个可执行文件,但你希望如何运行一个
  • @Tsyvarev 我明白了。但是图书馆是需要测试的东西。将库也导出为仅用于单元测试的可执行文件似乎很奇怪。我来自 C# 背景,通常我们不会出于测试目的将库发布为可执行文件。我可能期望它起作用的一种方法是创建一个单独的测试运行程序可执行文件,该可执行文件引用该库,然后运行测试(我尝试过,但它不起作用 - 这是 CMake 和单元测试的可行方法)?
  • 您的测试源文件可能不应包含在add_library() 987654335 @呼叫中,而是通过这样的呼叫中的呼叫:add_executable(Test1 tests/test.cpp)。这将使测试可执行 来测试您的库。使用 CTest 时,应使用add_test() 添加要由 CTest 运行的测试。 Here 是典型的 CTest 用法的一个很好的例子。

标签: c++ cmake catch2


【解决方案1】:

基于@Stephen Newell 和@squareskittles 的cmets,我最终修改的工作CMakeLists.txt 文件如下。

我在根文件中添加了enable_testing()。这使得 RUN_TESTS 项目在 Visual Studio 中可见。当我想运行测试时,我构建了这个项目:

cmake_minimum_required (VERSION 3.8)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
project("My.Project")

enable_testing()

add_executable(MyProject main.cpp)

# Copy all DLLs if windows:
if(WIN32)
    file(GLOB_RECURSE DYNAMIC_LIBS "${CMAKE_CURRENT_SOURCE_DIR}/*.dll")
    foreach(dll ${DYNAMIC_LIBS})
        add_custom_command(TARGET AZTEC_EDITOR POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy
            ${dll} $<TARGET_FILE_DIR:AZTEC_EDITOR>)
    endforeach()
else(APPLE)
endif()

add_subdirectory(core)
target_link_libraries(MyProject MyLib)

但是,仅添加这一行仍然会留下一个问题,即即使 RUN_TESTS 存在,它也没有发现单元测试,因为 CMake-Catch2 集成需要一个可执行文件,而不是一个库来运行测试。所以,我在核心文件夹的 CMakeLists.txt 文件中添加了一个单独的目标:

file(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")

add_library(MyLib ${HEADER_FILES} ${SOURCE_FILES})

target_include_directories(MyLib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")

# Copy all DLLs if windows:
if(WIN32)
    file(GLOB_RECURSE DYNAMIC_LIBS "${CMAKE_CURRENT_SOURCE_DIR}/*.dll")
    foreach(dll ${DYNAMIC_LIBS})
        add_custom_command(TARGET AZTEC_EDITOR_CORE POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy
            ${dll} $<TARGET_FILE_DIR:AZTEC_EDITOR_CORE>)
    endforeach()
else(APPLE)
endif()

# Catch2 stuff:
file(GLOB TEST_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp")
add_executable(MyLibTests ${TEST_FILES})

if(WIN32)
    find_package(Catch2 REQUIRED PATHS "${CMAKE_CURRENT_SOURCE_DIR}/deps/catch2/win32")
    target_link_libraries(MyLibTests Catch2::Catch2)
endif()

include(CTest)
include(Catch)
catch_discover_tests(MyLibTests)

由于 Catch2 文档中给出的示例相当少,希望这将有助于尝试将 Catch2 与更复杂的项目结构集成的人。感谢评论员的所有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多