【问题标题】:C++ testing classes with Catch使用 Catch 测试 C++ 类
【发布时间】:2015-07-12 00:09:20
【问题描述】:

我决定做一个小项目,我将尽可能多地进行测试。我正在使用 CLion(它使用 CMake)和 Catch 库进行测试。

问题是我在运行测试类时得到了undefined reference to TestClass::add 方法。

这是我的设置(这是一个虚拟设置,因为我想确保一切正常):

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 -- 包含测试的文件

#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})

【问题讨论】:

    标签: c++ testing cmake clion


    【解决方案1】:

    您没有指定要在LLL_TEST 可执行目标中编译的TestClass.{.h, .cpp}:

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

    或者最好将它移动到某个共享库中并链接到它。

    问题是因为您的项目产生了 2 个可执行文件:LLLLLL_TEST 目标。它们每个都有一个目标文件和一个引用。在LLL 目标中,这些对TestClass 的引用是满足的,因为它们是在LLL 目标中编译的,因此ld 可以简单地链接它们。但是如果LLL_TEST 目标编译器找不到这些符号,因为它们没有在这个目标中指定 - 这就是编译器说他无法解析引用的原因。

    【讨论】:

    • 谢谢,这行得通……但你能解释一下这部分:“或者最好将它移到某个共享库中并链接到它”?我对整个 C++ 和构建系统的东西并不陌生,并且使用了相当容易安装和使用的 Java 和 Python 库,所以我有点迷路了:/
    • @SvenVidak 如果对您有帮助 - 接受它作为答案,以便其他有此问题的人知道解决方案。关于图书馆 - 它需要非常非常大量的文本,也需要大量时间来理解。我建议你读一本关于CC++ 的好书。但在我看来,这些库仅在一些 unix/linux 书籍中得到了很好的解释。
    • 我必须再等 2 分钟才能接受答案。关于共享库 - 我对它们有一些了解,但据我所知,每次我想测试某些东西时都必须重新创建它们,如果我想做 TDD 之类的事情,那真的很烦人。我说的对吗?
    • 如果你这样做 TDD - 是的。当然,您应该考虑项目的架构并对其进行优化。
    • 我想澄清一下,是的,您每次更改某些内容并想要对其进行测试时都需要重新创建库,但如果您按照 tamas.kenez 的回答进行设置,则过程是一点也不累,它就像定期重建一样,无论如何你都必须像在 java 中那样做。
    【解决方案2】:

    Polevoy 已经回答了您的问题,而且他也正确地将您的课程分解到库中。

    我只想展示库版本的外观。你可以决定它是否真的那么复杂你需要看书,或者它是否有任何开销来做 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)
    

    此脚本创建静态库LLL_LIB,它链接到两个可执行文件。如果您愿意,您可以构建一个共享的:

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

    但静态在这里就好了。

    【讨论】:

      猜你喜欢
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 2013-06-30
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      相关资源
      最近更新 更多