Search code examples
c++visual-studiocmakecatch2

Catch2 with CMake and Visual Studio


I'm trying to setup Catch2 test framework for a library I have built. I'm using CMake and Visual Studio 2017.

My project structure is:

executable-project/
|-- library
      |--include/
      |    |--SUT.h 
      |--src/
      |    |--SUT.cpp
      |--tests/
      |    |--catch.hpp
      |    |--SUTTest.cpp
      |CMakeLists.txt
|include/
|src/
| |--main.cpp
|CMakeLists.txt

SUT.h, SUT.cpp and SUTTest.cpp are just testing a factorial function defined based on the example.

My CMakeLists.txt file in the library is

cmake_minimum_required (VERSION 3.8)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

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(MY_LIBRARY ${HEADER_FILES} ${SOURCE_FILES} ${TEST_FILES})

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

source_group("Test Files" FILES ${TEST_FILES})

The SUTTest.cpp file is:

#define CATCH_CONFIG_MAIN

#include "catch.hpp"
#include "SUT.h"

TEST_CASE("Factorials are computed", "[factorial]")
{
    SUT sut;

    REQUIRE(sut.Factorial(0) == 0);
    REQUIRE(sut.Factorial(1) == 1);
    REQUIRE(sut.Factorial(2) == 2);
    REQUIRE(sut.Factorial(3) == 6);
    REQUIRE(sut.Factorial(10) == 3628800);
}

The "executable-project" simply makes use of the library (it's the actual application). The CMakeLists.txt in that project dynamically links the library to it.

When I build this solution in Visual Studio, build works fine.

However, the test isn't failing despite asserting that the Factorial(0) == 0. Also, Visual Studio is not discovering the tests in the tests folder. What I'm trying to achieve are:

  1. When I click on Build in Visual Studio, the tests to be run as part of the build.

  2. (Optional) to be able for Visual Studio to discover the tests.

EDIT:

cmake_minimum_required (VERSION 3.8)

project("My Project")

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

add_subdirectory(library)
add_executable(MY_APP main.cpp ${HEADER_FILES} ${SOURCE_FILES})

target_include_directories(MY_APP PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(MY_APP MY_LIBRARY)

Solution

  • Finally managed to get Catch2 to work with Visual Studio.

    First I downloaded Catch2 release from their GitHub and installed it on my computer using (this is actually documented here).

    cmake -Bbuild -S. -DBUILD_TESTING=OFF
    cmake --build build/ --target install (Need admin rights)
    

    This installs Catch2 in C:\Program Files (x86)\Catch2. Then I copied everything in this install directory to my project's deps/Catch2 folder. Then just add the below to the CMakeLists.txt:

    find_package(Catch2 REQUIRED PATHS "${CMAKE_CURRENT_SOURCE_DIR}/deps/Catch2")
    target_link_libraries(MY_LIBRARY Catch2::Catch2)
    
    include(CTest)
    include(Catch)
    catch_discover_tests(MY_LIBRARY)
    

    This adds the RUN_TESTS project to Visual Studio. When I build this project, my unit tests run. Hope this is helpful to anyone trying to integrate with CMake.