C++ 单元测试在运行所有测试时或在某个测试之后失败

标签 c++ unit-testing cmake googletest

我正在使用 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 中的 TESTTEST_F 宏之间的区别 - 后者表示基于测试夹具的测试。

googletest AdvancedGuide 有很多关于使用测试夹具的信息:

https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#sharing-resources-between-tests-in-the-same-test-case

当您将 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/

相关文章:

c++ - 在 C++ 中继承抽象模板类并指定类型

c++ - 带有 epgm 的 ZeroMQ PUB/SUB 无法接收同一主机上进程发送的消息

ruby - 是否可以在不调用初始化的情况下实例化 Ruby 类?

java - 我面临类转换异常,从 java.lang.Double 到 java.lang.Integer

ScalaTest 共享行为函数提前失败

c++ - 在 CMake 中调试与发布

c++ - 否定多个类型 std::size_t 的安全方法

c++ - 创建柯南 test_package 配方

ubuntu - cmake构建错误,文件似乎不存在

c++ - cuda 内存分配 cudaMalloc