【问题标题】:GoogleTest CMake and Make tests not runningGoogleTest CMake 和 Make 测试未运行
【发布时间】:2015-07-18 08:28:29
【问题描述】:

我承认我有一个独特的情况。我们使用 Make 构建我们的应用程序。但是我的 IDE CLion 使用 CMake。因此,我尝试将 GoogleTest 设置为在两者(某种)上运行。我可以两种方式编译我的代码(在命令行使用 make 并从我的 IDE 构建)。但是在 CLion 中,当我选择测试夹具并单击运行按钮时,没有找到任何测试,这就是我收到的:

Running main() from gtest_main.cc  
[==========] Running 0 tests from 0 test cases.  
[==========] 0 tests from 0 test cases ran. (0 ms total)  
[ PASSED  ] 0 tests.

Process finished with exit code 0

这是我的测试夹具:

#include <gtest/gtest.h>
#include "OPProperties.h"

namespace {
// The fixture for testing class OPPropertiesTestTest.
    class OPPropertiesTestTest : public ::testing::Test {
    protected:
        // You can remove any or all of the following functions if its body
        // is empty.

        OPPropertiesTestTest() {
            // You can do set-up work for each test here.
        }

        virtual ~OPPropertiesTestTest() {
            // You can do clean-up work that doesn't throw exceptions here.
        }

        // If the constructor and destructor are not enough for setting up
        // and cleaning up each test, you can define the following methods:

        virtual void SetUp() {
            // Code here will be called immediately after the constructor (right
            // before each test).
        }

        virtual void TearDown() {
            // Code here will be called immediately after each test (right
            // before the destructor).
        }

        // Objects declared here can be used by all tests in the test case for OPPropertiesTestTest.
    };

    TEST_F(OPPropertiesTestTest, ThisTestWillPass) {
        EXPECT_EQ(0, 0);
    }

    TEST_F(OPPropertiesTestTest, ThisTestWillFail) {
        EXPECT_EQ(0, 5);
    }


}  // namespace


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

这是我的 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 2.8)
project(oneprint)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -lgtest")
add_definitions(-DBOOST_LOG_DYN_LINK)


set(SOURCE_FILES
    src/controllers/OPProperties.cpp
    src/controllers/OPProperties.h
    src/main.cpp)

include_directories(src/controllers)

set(BOOST_ROOT "/usr/local/lib")
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
unset(Boost_INCLUDE_DIR CACHE)
unset(Boost_LIBRARY_DIRS CACHE)
#set(Boost_LIBRARY_DIR /usr/local/arm/lib)
set(OpenCV_LIBRARY_DIR /usr/include/opencv2)
set(Innovatrics_LIBRARY_DIR /usr/local/arm/lib)

find_package(OpenCV REQUIRED)

find_package(Boost 1.57.0 COMPONENTS filesystem thread log chrono system atomic program_options REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})

enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})

add_executable(OnePrint ${SOURCE_FILES})

target_link_libraries(OnePrint ${OpenCV_LIBS})
target_link_libraries(OnePrint ${Boost_LIBRARIES})
target_link_libraries(OnePrint ${Innovatrics_LIBRARY_DIR})
target_link_libraries(OnePrint ${GTEST_BOTH_LIBRARIES})
target_link_libraries(OnePrint pthread)

我在 src 下添加了一个名为 tests 的文件夹,这是我的测试夹具 OPPropertiesTestTest 所在的位置。我还在顶层添加了一个测试文件夹。此文件夹中包含一个 Makefile 和一个 Srcs.mak 文件。

这是 Makefile:

TARGET = oneprint
BASE = ../

-include $(BASE)Defs.x86.mak
-include $(BASE)OpenCV.mak
-include $(BASE)Boost.mak
-include $(BASE)Innovatrics.mak
-include $(BASE)GTest.mak

-include $(BASE)Incl.mak
-include Srcs.mak

-include $(BASE)Common.mak
-include $(BASE)App.mak

这里是 Srcs.mak 文件:

VPATH = \
../src/controllers:\
../src:\
../src/tests

CPP_SRCS = \
OPProperties.cpp \

# test files
CPP_SRCS += \
OPPropertiesTest.cpp

【问题讨论】:

  • 为什么要将测试放在匿名命名空间中?
  • 请注意,我是 C++ 和 CMake 和 Make 以及 GoogleTest 的新手......(有很多要消化的东西,嗯?)。这就是他们在示例中的内容? !就此而言,我不确定是否应该将其放在名称空间中。我很想听听您的建议。
  • 匿名命名空间很好,我有这样的测试,而且它也在示例中,应该不是问题。

标签: c++ linux makefile cmake googletest


【解决方案1】:

我通常不希望看到 makefile 混入 CMake 管理的项目中;听起来您的设置相当复杂?

除此之外,我认为这里的根本原因可能是双重的。我不认为/src/tests/ 中的测试可执行文件实际上正在构建中。我在你的 CMakelists.txt 中看不到任何会导致它被构建的东西,所以除非你做一些你没有向我们展示的额外的东西,否则测试文件不会被编译。

可能使它们看起来像的原因是,您正在将 gtest 提供的帮助程序库链接到您的 OnePrint 目标中。这个帮助程序库的不寻常之处在于它实现了一个main() 函数来节省用户必须指定自己的函数。

你在这条线上这样做

target_link_libraries(OnePrint ${GTEST_BOTH_LIBRARIES})

来自the docs GTEST_BOTH_LIBRARIES 是一个包含 libgtest 和 libgtest-main 的变量。您只需要 libgtest,因为您已经编写了自己的 main()。所以你应该改用GTEST_LIBRARIES


注意:CMake 代码还有一些其他问题:

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

这不是跨平台的(这对您来说可能无关紧要),例如MSVC 不会识别任何这些标志。如果它确实重要,您需要将其包装在 if(UNIX)if(NOT MSVC) 块中。

此外,这会全局设置编译器标志,即为您项目中定义的每个目标。如果您需要更细粒度的控制,请查看target_compile_options,它可以让您指定这些每个目标。

另一个问题是-lgtest 部分。这实际上是对链接器的调用以链接 gtest 库。但是,CMake 会为您处理这些 - 当您致电 target_link_libraries(OnePrint ${GTEST_LIBRARIES}) 时,您正在执行此操作。


add_definitions(-DBOOST_LOG_DYN_LINK)

虽然这很好,但有关此全局应用的相同 cmets 也适用。每个目标的等价物是 target_compile_definitions


set(BOOST_ROOT "/usr/local/lib")

这可能是你的机器上 Boost 的位置,但对于其他开发者来说可能不是这样。该变量实际上是由单个用户在调用 CMake 时指定的(如果需要...许多路径由 CMake 自动搜索) - 您不应该将这样的路径硬编码到 CMake 文件中。


target_link_libraries(OnePrint pthread)

同样,如果您使用 MSVC,pthread 不适合链接;这可能应该包含在 if 块中。


最后一点是您可以在target_link_libraries 命令中指定多个依赖项,因此您可以将它们更改为:

if(NOT MSVC)
  set(PThreadLib pthread)
endif()
target_link_libraries(OnePrint
    ${OpenCV_LIBS}
    ${Boost_LIBRARIES}
    ${Innovatrics_LIBRARY_DIR}
    ${GTEST_LIBRARIES}
    ${PThreadLib})

【讨论】:

  • 嘿,弗雷泽:很高兴你能看一看。这是一些非常有用的信息。谢谢你。 :-) 是的,这是一个相当复杂的设置。我在 youtube 上找到了这些 FANTASTIC 教程,用于使用 NetBeans 使用 Make 设置 GoogleTest。我真的对这两个项目的事情感到困惑,而博倩的教程说得一清二楚。因此,在 CLion 可以支持 Make 之前,我将使用 NetBeans。教程位于:youtube.com/…
  • 嗨,露西。很高兴你得到这个工作。你的项目是开源的吗?即我可以偷看一下吗?
  • 不,伙计,它不是开源的。我想它的一部分可能在未来,但我们是世界上领先的非接触式指纹公司。这段代码被锁得很紧。对不起,伙计!
  • 非接触式指纹识别听起来很酷,但不用担心——我可以对实际的 CMake 文件进行拉取请求。既然我不能,我只会在我的答案中添加更多的 cmets。等待更新:)
  • 弗雷泽:这太棒了!!!我希望我能给你更多的分数。但我想我确实做到了,因为我对你关于 GoogleTest 的所有答案都投了赞成票。 :-)
猜你喜欢
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
相关资源
最近更新 更多