Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ testing classes with Catch

I decided to make a small project which I will cover with tests as much as I can. I'm using CLion (which uses CMake) and Catch library for testing.

The problem is that I'm getting undefined reference to TestClass::add method while I run test class.

Here is my setup (it's a dummy one since I wanted to make sure if everything works):

TestClass.h

#ifndef LLL_TESTCLASS_H
#define LLL_TESTCLASS_H

class TestClass {
public:
    int add(int a, int b);
};

#endif //LLL_TESTCLASS_H

TestClass.cpp

#include "TestClass.h"
int TestClass::add(int a, int b) {
    return a + b;
}

test.cpp -- file with tests

#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "../src/TestClass.h"

TEST_CASE("addition") {
    TestClass testClass;
    REQUIRE(testClass.add(2,3) == 5);
    REQUIRE(testClass.add(-1, 1) == 0);
    REQUIRE(testClass.add(2, 4) == 1);
}

CMakeLIsts.txt

cmake_minimum_required(VERSION 3.2)
project(LLL)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(LIB_DIR "lib")
include_directories(${LIB_DIR}/Catch)
include_directories(${LIB_DIR}/Eigen)

set(SRC_DIR src)
set(SOURCE_FILES ${SRC_DIR}/main.cpp src/TestClass.h src/TestClass.cpp)
add_executable(LLL ${SOURCE_FILES})

set(TEST_DIR test)
set(TEST_FILES ${TEST_DIR}/test.cpp)
add_executable(LLL_TEST ${TEST_FILES})
like image 614
Sven Vidak Avatar asked Jul 12 '15 00:07

Sven Vidak


People also ask

Can I use Gtest for C?

It is pretty common to test C code using a C++ testing frameworks, even the leading book on the subject follows this approach. I have used googletest extensively in the past to unit test C code and can recommend it.

Does Catch2 work for C?

In most cases, the answer is yes.

What is a catch test?

Catch Can Test of Water Efficiency A catch can test is used to determine how long to run an irrigation system or hose-end sprinkler and how well the water is distributed over the landscape.

Where can I get catch HPP?

Head straight to github.com/catchorg/Catch2 and download the catch2. hpp file from the link in the README. All you need to do is drop the file somewhere reachable from your project, either in some central location you can set your header search path to find, or directly into your project tree itself!


2 Answers

You did not specify the TestClass.{.h, .cpp} to be compiled in LLL_TEST executable target:

set(TEST_FILES src/TestClass.h src/TestClass.cpp ${TEST_DIR}/test.cpp)

Or better move it in some shared library and just link to it.

The problem is because your project produces 2 executables: LLL and LLL_TEST targets. Each of them have a object files and a references. In LLL target these references to TestClass are satistifed because they are compiled in the LLL target so the ld can simply link them. But in case of LLL_TEST target compiler can't find these symbols because they are not specified in this target - that's why compiler says that he can't resolve a reference.

like image 124
Victor Polevoy Avatar answered Oct 29 '22 03:10

Victor Polevoy


Your question has already been answered by Polevoy and he's also correct about factorizing out your class to a library.

I'd just like to show how the library version would look like. You can decide whether it's really so complicated you need to read books or if it has any overhead for doing TDD.

cmake_minimum_required(VERSION 3.2)
project(LLL)

set(CMAKE_CXX_STANDARD 11) # adds -std=c++11
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(LIB_DIR "lib")
include_directories(${LIB_DIR}/Catch)
include_directories(${LIB_DIR}/Eigen)

add_library(LLL_LIB src/TestClass.h src/TestClass.cpp)

add_executable(LLL src/main.cpp)
target_link_libraries(LLL LLL_LIB)

add_executable(LLL_TEST test/test.cpp)
target_link_libraries(LLL_TEST LLL_LIB)

This script creates the static library LLL_LIB which is linked into both executables. You can build a shared one instead if you like:

add_library(LLL_LIB SHARED src/TestClass.h src/TestClass.cpp)

but static is just fine here.

like image 42
tamas.kenez Avatar answered Oct 29 '22 02:10

tamas.kenez