2

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)
kovac
  • 4,945
  • 9
  • 47
  • 90

2 Answers2

1

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.

kovac
  • 4,945
  • 9
  • 47
  • 90
0

the test isn't failing despite asserting that the Factorial(0) == 0

You should assert what is true/expected. Then if your written code is wrong, it will fail.

REQUIRE( Factorial(0) == 1 ); (not == 0)

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

Within the Visual Studio IDE, the build and run are two separate steps. If you want to sequence it automatically, write a simple .bat script which first builds and then runs.

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

Catch2 has CMake integration which contains CMake scripts for automatic registration of TEST_CASEs in CTest.

cmake_minimum_required(VERSION 3.5)

project(baz LANGUAGES CXX VERSION 0.0.1)

find_package(Catch2 REQUIRED)
add_executable(foo test.cpp)
target_link_libraries(foo Catch2::Catch2)

include(CTest)
include(Catch)
catch_discover_tests(foo)

See Catch2 CMake Integration for details.

ap-osd
  • 2,624
  • 16
  • 16