C++ Google测试CMake并使测试不运行

C++ Google测试CMake并使测试不运行,c++,linux,makefile,cmake,googletest,C++,Linux,Makefile,Cmake,Googletest,我承认我有一个独特的情况。我们使用Make构建应用程序。但我的IDE CLion使用CMake。所以我尝试设置GoogleTest在这两个平台上运行(有点)。我可以用两种方式编译代码(在命令行使用make和从IDE编译)。但在CLion中,当我选择测试夹具并单击run按钮时,没有找到任何测试,这就是我收到的结果: Running main() from gtest_main.cc [==========] Running 0 tests from 0 test cases. [=====

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

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();
}
我在src下添加了一个名为tests的文件夹,这是我的测试夹具OPPropertiesTestTest所在的位置。我还在顶层添加了一个测试文件夹。此文件夹中包含一个Makefile和一个Srcs.mak文件

以下是生成文件:

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

我通常不会期望看到makefiles被混合到CMake管理的项目中;听起来你的设置很复杂

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

可能是因为您正在将gtest提供的帮助程序库链接到您的
OnePrint
目标中。这个helper库与众不同,因为它实现了一个
main()
函数,用户无需指定自己的helper库

你是在排队吗

target_link_libraries(OnePrint ${GTEST_BOTH_LIBRARIES})
From
GTEST\u两个库
是一个同时包含libgtest和libgtest main的变量。您只需要libgtest,因为您已经编写了自己的
main()
。因此,您应该使用
GTEST_库


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

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -lgtest")
这不是跨平台的(这对您来说可能无关紧要),例如,MSVC不会识别任何这些标志。如果这很重要,您需要将其包装在
If(UNIX)
If(非MSVC)
块中

此外,这将全局设置编译器标志,即为项目中定义的每个目标设置编译器标志。如果您需要更细粒度的控制,请查看哪些控件允许您为每个目标指定这些控件

另一个问题是
-lgtest
部分。这实际上是对链接器的调用,以链接gtest库。但是,CMake会为您解决这个问题—您在调用
target\u link\u库(OnePrint${GTEST\u libraries})
时就是这样做的


虽然这很好,但同样的评论也适用于全球。每个目标的等效值为


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


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


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

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

为什么你要把测试放在匿名的命名空间里?请注意我是C++和CMake的新手,做GoGeLestTest……(有很多东西要消化,嗯?)这就是他们在这个例子中所做的!因此,我不确定是否应该将它放在名称空间中。我很想听听你的建议。匿名名称空间很好,我有这样的测试,也在示例中,应该不会有问题。嘿,弗雷泽:很高兴你能看一下。这是一些非常有用的信息。谢谢。:-)是的,这是一个相当复杂的设置。我在youtube上找到了这些关于使用NetBeans设置GoogleTest和Make的精彩教程。我真的对这两个项目感到困惑,而薄熙来的教程让我非常清楚。所以,在CLion支持Make之前,我将使用NetBeans。教程位于这里:嗨,露西。很高兴你成功了。你的项目是开源的吗?i、 我能看一眼吗?不,伙计,这不是开源的。我想未来可能会有一部分,但我们是世界上领先的非接触式指纹公司。这个密码锁得很紧。对不起,巴德!非接触式指纹听起来很酷,但不用担心——只是我可以在实际的CMake文件上做一个拉取请求。既然我不能,我只想在我的回答中添加更多的评论。等待更新:)弗雷泽:这太棒了!!!我希望我能对这个答案给你更多的分数。但我想我是这样做的,因为我已经把你所有关于谷歌测试的答案都投了赞成票。:-)
add_definitions(-DBOOST_LOG_DYN_LINK)
set(BOOST_ROOT "/usr/local/lib")
target_link_libraries(OnePrint pthread)
if(NOT MSVC)
  set(PThreadLib pthread)
endif()
target_link_libraries(OnePrint
    ${OpenCV_LIBS}
    ${Boost_LIBRARIES}
    ${Innovatrics_LIBRARY_DIR}
    ${GTEST_LIBRARIES}
    ${PThreadLib})