使用CMake最小化为简单标头构建测试

问题描述

我有一个C ++标头,其中包含带有如下方法的类。可以说它是我仅有的标头库。

// MyHeader.hpp
#pragma once

#include <string>

namespace myheaderonlylibrary {

class MyClass {
public:
    unsigned int Func1(const std::string& str) {
        if (!str.empty())
            return 10;
        else
            return 0;
    }
};

}

要测试上述方法,我将以下gtest源文件放在名为unittest文件夹中,就像遵循的约定一样。

// MyTests.cpp
#include <limits.h>
#include "gtest/gtest.h"

#include "../MyHeader.hpp"

TEST(MyTest,Test_Something) {
    myheaderonlylibrary::MyClass my_object;
    unsigned int expected_value = 0;
    EXPECT_EQ(expected_value,my_object.Func1(""));
}

要做的就是使用Cmake构建测试并运行测试。因此,以下是我的CMakeLists.txt

// CMakeLists.txt
cmake_minimum_required(VERSION 3.4)
set(MyheaderOnlyLibrary_HEADERS
    MyHeader.hpp
)

set(MyheaderOnlyLibrary_unittest
    unittest/MyTests.cpp
)

find_package(GTest required)
enable_testing ()
add_executable(MyheaderOnlyLibraryTests ${MyheaderOnlyLibrary_unittest})

完成上述设置后,我执行了cmake ..make,结果是出现以下错误

"_main",referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64

问题:
我不是CMake的专家。我的问题是,如果我想做的就是能够运行测试,那我应该做一个add_executable吗?当我唯一想要的是构建并运行测试时,这种方法正确吗?似乎在调用make时出现错误是因为add_executable正在像普通可执行文件中那样寻找main方法,但找不到它。

在仅测试头文件的情况下,构建仅测试项目的正确方法是什么?

构建后如何运行测试?看起来好像有一条命令CTest运行使用CMake构建的测试吗?

环境:
我正在使用clang作为C ++ 11的编译器在macOS上构建它。

解决方法

就像普通的C ++程序一样,您需要具有一个主要的函数才能执行,对于googletest单元测试,您可以使用以下代码:

int main(int argc,char** argv)
{
    testing::InitGoogleTest(&argc,argv);
    return RUN_ALL_TESTS();
 }

这将在执行时运行您的TEST函数。

要使用ctest实际运行测试,您的cmake文件中应包含以下几行:

find_package(GTest)
include_directories(${GTEST_INCLUDE_DIRS})

include(CTest)
include(GoogleTest)

enable_testing()

target_link_libraries(testName ${GTEST_LIBRARIES})

gtest_discover_tests(testName)

编辑: 作为进入cmake之前更容易开始的地方,我建议您从在命令行上编译并运行命令开始。您可以执行以下操作:

g++ unittest/myunittest.cpp -o unittest/myunittest.out -lgtest -std=c++11
./unittest/myunittest.out

一旦知道它可以工作,请查看cmake的文档,并使用cmake文件复制结果。然后,您可以开始扩展您的程序。了解如何通过命令行运行这些命令将使您对cmake的工作有所了解和了解。