GoogleTest CMake 和 Make 测试不是 运行
GoogleTest CMake and Make tests not running
我承认我的情况很特殊。我们使用 Make 构建我们的应用程序。但是我的 IDE,CLion,使用 CMake。所以我尝试将 GoogleTest 设置为 运行 两者(有点)。我可以用两种方式编译我的代码(在命令行使用 make 并从我的 IDE 构建)。但是在 CLion 中,当我 select 测试夹具并单击 运行 按钮时,没有找到任何测试,这就是我收到的:
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 文件。
这是生成文件:
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
我通常不希望看到 makefile 被混合到 CMake 管理的项目中;听起来你的设置很复杂?
除此之外,我认为这里的根本原因可能是双重的。我不认为 /src/tests/
中的测试可执行文件实际上正在构建。我在你的 CMakelists.txt 中看不到任何会导致它被构建的东西,所以除非你正在做一些你没有向我们展示的额外事情,否则测试文件不会被编译。
可能使它们看起来像的是,您正在 link 将 gtest 提供的帮助程序库整合到您的 OnePrint
目标中。这个帮助程序库的不寻常之处在于它实现了一个 main()
函数来避免用户必须自己指定。
你在行中这样做
target_link_libraries(OnePrint ${GTEST_BOTH_LIBRARIES})
From 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
部分。这实际上是对 link er link gtest 库的调用。但是,CMake 会为您处理 - 您在调用 target_link_libraries(OnePrint ${GTEST_LIBRARIES})
.
时正在执行此操作
add_definitions(-DBOOST_LOG_DYN_LINK)
虽然这很好,但关于此在全球范围内应用的相同评论也适用。每个目标等效为 target_compile_definitions
.
set(BOOST_ROOT "/usr/local/lib")
这可能是 Boost 在您的 机器上的位置,但对于其他开发者而言可能并非如此。该变量实际上是由个人用户在调用 CMake 时指定的(如果需要......CMake 会自动搜索许多路径) - 你不应该将这样的路径硬编码到 CMake 文件中。
target_link_libraries(OnePrint pthread)
同样,如果您使用的是 MSVC,pthread
将不适合 link;这可能应该包含在 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})
我承认我的情况很特殊。我们使用 Make 构建我们的应用程序。但是我的 IDE,CLion,使用 CMake。所以我尝试将 GoogleTest 设置为 运行 两者(有点)。我可以用两种方式编译我的代码(在命令行使用 make 并从我的 IDE 构建)。但是在 CLion 中,当我 select 测试夹具并单击 运行 按钮时,没有找到任何测试,这就是我收到的:
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 文件。
这是生成文件:
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
我通常不希望看到 makefile 被混合到 CMake 管理的项目中;听起来你的设置很复杂?
除此之外,我认为这里的根本原因可能是双重的。我不认为 /src/tests/
中的测试可执行文件实际上正在构建。我在你的 CMakelists.txt 中看不到任何会导致它被构建的东西,所以除非你正在做一些你没有向我们展示的额外事情,否则测试文件不会被编译。
可能使它们看起来像的是,您正在 link 将 gtest 提供的帮助程序库整合到您的 OnePrint
目标中。这个帮助程序库的不寻常之处在于它实现了一个 main()
函数来避免用户必须自己指定。
你在行中这样做
target_link_libraries(OnePrint ${GTEST_BOTH_LIBRARIES})
From 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
部分。这实际上是对 link er link gtest 库的调用。但是,CMake 会为您处理 - 您在调用 target_link_libraries(OnePrint ${GTEST_LIBRARIES})
.
add_definitions(-DBOOST_LOG_DYN_LINK)
虽然这很好,但关于此在全球范围内应用的相同评论也适用。每个目标等效为 target_compile_definitions
.
set(BOOST_ROOT "/usr/local/lib")
这可能是 Boost 在您的 机器上的位置,但对于其他开发者而言可能并非如此。该变量实际上是由个人用户在调用 CMake 时指定的(如果需要......CMake 会自动搜索许多路径) - 你不应该将这样的路径硬编码到 CMake 文件中。
target_link_libraries(OnePrint pthread)
同样,如果您使用的是 MSVC,pthread
将不适合 link;这可能应该包含在 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})