我正在使用 GoogleTest 进行单元测试,今天当我添加一个新测试时,我发现它在单独运行时通过,而在运行所有测试时失败。我已经阅读了一些问题和答案,但它们链接到 C#。
我使用 C++ 和 CMake 来执行此操作。
我的 CMakeLists.txt 看起来像这样:
cmake_minimum_required(VERSION 2.8)
option(test "Build all tests." OFF)
set(EXECUTABLE_NAME proj)
project(${EXECUTABLE_NAME})
set(CMAKE_CXX_FLAGS "-g -Wall")
include_directories(src/main/cpp
${Boost_INCLUDE_DIRS}
)
find_package(OpenCV REQUIRED core
imgproc
highgui
)
find_package(Boost REQUIRED COMPONENTS filesystem
system
regex
program_options
)
add_executable( ${EXECUTABLE_NAME}
# .........
)
target_link_libraries(${EXECUTABLE_NAME} ${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
)
if (test)
find_package(GTest REQUIRED)
enable_testing()
include_directories( ${GTEST_INCLUDE_DIRS} )
add_executable(${EXECUTABLE_NAME}_test1
# .............
)
add_executable(${EXECUTABLE_NAME}_test2
# .............
)
add_executable(${EXECUTABLE_NAME}_test3
# .............
)
add_executable(${EXECUTABLE_NAME}_test4
# .............
)
target_link_libraries(${EXECUTABLE_NAME}_test1
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
${GTEST_LIBRARIES}
gtest_main
pthread
)
target_link_libraries(${EXECUTABLE_NAME}_test1
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
${GTEST_LIBRARIES}
gtest_main
pthread
)
target_link_libraries(${EXECUTABLE_NAME}_test2
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
${GTEST_LIBRARIES}
gtest_main
pthread
)
target_link_libraries(${EXECUTABLE_NAME}_test3
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
${GTEST_LIBRARIES}
gtest_main
pthread
)
target_link_libraries(${EXECUTABLE_NAME}_test4
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
${GTEST_LIBRARIES}
gtest_main
pthread
)
add_test(${EXECUTABLE_NAME}_test1
${EXECUTABLE_NAME}_test1
)
add_test(${EXECUTABLE_NAME}_test2
${EXECUTABLE_NAME}_test2
)
add_test(${EXECUTABLE_NAME}_test3
${EXECUTABLE_NAME}_test3
)
add_test(${EXECUTABLE_NAME}_test4
${EXECUTABLE_NAME}_test4
)
endif()
我使用这样的测试:
#pragma once
#include <gtest/gtest.h>
#include "My.hpp"
/** Testing
*/
TEST(qsdf, asdf)
{
// ... initialization
// ... test
}
我尝试使用 TEST_F
而不是 TEST
但是它崩溃了,它说 qsdf 没有声明(我不得不承认我之前没有做过很多单元测试).
我读到其他测试有可能修改了某些东西,我认为这是真的,因为我在其他一些测试再次失败后单独运行测试。
我的问题是:如何使用 CMake(在 Linux 下,如果重要的话)在 C++ 中初始化每个测试?
最佳答案
这听起来确实像是一个涉及共享资源的问题(正如您所怀疑的那样)。
每个测试的初始化完全在您的测试文件中完成,没有 CMake 等的任何额外参与。正如您提到的,测试通常包括一个初始化阶段,然后是实际测试。此外,包含在测试完成后发生的清理 步骤也很常见。例如:
TEST(qsdf, asdf)
{
// ... initialization
// ... test
// ... **cleanup**
}
通常,初始化和清理阶段只涉及分配和释放测试中使用的变量。但这些阶段通常是为运行测试做准备,并在测试后进行清理。
如果您正在测试共享资源的代码,那么初始化阶段包括根据需要初始化这些资源; 清理阶段包括将这些资源重置回初始化阶段之前的状态。
当您有共享资源的测试时,使用测试夹具来协调资源的初始化/清理会很有帮助。这是 googletest 中的 TEST
和 TEST_F
宏之间的区别 - 后者表示基于测试夹具的测试。
googletest AdvancedGuide 有很多关于使用测试夹具的信息:
当您将 TEST
更改为 TEST_F
时,您的代码中断的原因是您没有定义测试期望找到的测试夹具,这是第一个宏的参数。在 googletest 中,测试夹具只是一个继承自 ::testing::Test
类的类,因此您需要执行如下操作:
#pragma once
#include <gtest/gtest.h>
#include "My.hpp"
class MyTestFixture : public ::testing::Test
{
public:
virtual void SetUp() // This is defined in ::gtest::Test and overridden here
{
// This code will run before every test that uses this fixture
}
virtual void TearDown() // This is defined in ::gtest::Test and overridden here
{
// This code will run after every test that uses this fixture
}
};
/** Testing
*/
TEST_F(MyTestFixture, asdf)
{
// ... initialization (after SetUp)
// ... test
// ... cleanup (before TearDown)
}
关于C++ 单元测试在运行所有测试时或在某个测试之后失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22692081/