Googletest Parametrized测试崩溃

时间:2013-01-16 17:09:42

标签: c++ unit-testing googletest

我刚刚了解了value-parametrized unit tests in googletest并希望在我的项目中使用它们。

我写了一个简单的参数化测试。

部首:

#include <gtest/gtest.h>

namespace EnsembleClustering {

class ParametrizedGTest: public testing::TestWithParam<int> {
public:
    ParametrizedGTest();
    virtual ~ParametrizedGTest();
};

} /* namespace EnsembleClustering */

来源:

#include "ParametrizedGTest.h"

namespace EnsembleClustering {

ParametrizedGTest::ParametrizedGTest() {
    // TODO Auto-generated constructor stub

}

ParametrizedGTest::~ParametrizedGTest() {
    // TODO Auto-generated destructor stub
}


TEST_P(ParametrizedGTest, testParameter) {
    int n = GetParam();
    EXPECT_EQ(n, GetParam());
}


INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
                        ParametrizedGTest,
                        ::testing::Values(100));

} /* namespace EnsembleClustering */

现在,当我像往常一样运行googletest时,程序崩溃而没有任何输出。 gdb堆栈跟踪是

EnsembleClustering-D [C/C++ Application]    
    EnsembleClustering  
        Thread [1] (Suspended : Signal : EXC_BAD_ACCESS:Could not access memory)    
            __gnu_debug::_Safe_sequence_base::_M_attach_single() at 0x100528add 
            __gnu_debug::_Safe_sequence_base::_M_attach() at 0x100528a74    
            __gnu_debug::_Safe_iterator_base::_M_attach() at 0x100528bfe    
            __gnu_debug::_Safe_iterator_base::_Safe_iterator_base() at safe_base.h:90 0x1000016e9   
            __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<testing::internal::ParameterizedTestCaseInfoBase**, std::__cxx1998::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >, std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >::_Safe_iterator() at safe_iterator.h:154 0x100002e9c    
            std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> >::begin() at vector:207 0x100001fbe  
            testing::internal::ParameterizedTestCaseRegistry::GetTestCasePatternHolder<EnsembleClustering::ParametrizedGTest>() at gtest-param-util.h:574 0x1000025b0   
            EnsembleClustering::ParametrizedGTest_testParameter_Test::AddToRegistry() at ParametrizedGTest.cpp:22 0x100001d3f   
            __static_initialization_and_destruction_0() at ParametrizedGTest.cpp:22 0x100001349 
            _GLOBAL__sub_I_ParametrizedGTest.cpp() at ParametrizedGTest.cpp:32 0x100001424  
            <...more frames...> 
    gdb 

我做错了什么或者这是googletest中的错误?你能重现这个错误吗?

编辑:我使用的是Mac OS X 10.8。

2 个答案:

答案 0 :(得分:1)

从查看gtest的源代码来看,如果没有可用的参数化测试的唯一情况是在Windows上使用VC7.1并禁用例外:

// We don't support MSVC 7.1 with exceptions disabled now.  Therefore
// all the compilers we care about are adequate for supporting
// value-parameterized tests.
#define GTEST_HAS_PARAM_TEST 1

那么,你需要检查你的MinGW是如何构建的并且可能会更新它?你可以运行gtest单元测试来查看它们是否执行了类型参数测试吗?

有关MinGW的更多信息:

在他们的FAQ他们报告说使用MinGW时需要以下编译选项来构建gtest:PATH/TO/configure CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin"

完整示例:

#include <gtest/gtest.h>
namespace EnsembleClustering {

    class ParametrizedGTest: public testing::TestWithParam<int> {
    public:
        ParametrizedGTest();
        virtual ~ParametrizedGTest();
    };

    ParametrizedGTest::ParametrizedGTest() {
    }

    ParametrizedGTest::~ParametrizedGTest() {
    }

    TEST_P(ParametrizedGTest, testParameter) {
        int n = GetParam();
        EXPECT_EQ(n, GetParam());
    }

    INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
                            ParametrizedGTest,
                            ::testing::Values(100));

} /* namespace EnsembleClustering */


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

我在Mac OS X 10.8上使用以下编译器调用编译了此代码:

g++ -IGTEST_INCLUDE_DIR -LGTEST_LIB_DIR -lgtest -o tt2 tt2.cpp

其中GTEST_INCLUDE_DIRGTEST_LIB_DIR是存储标头和库文件的路径。编译和执行时,会发生什么?

答案 1 :(得分:0)

感谢@ChristianStaudt和@grundprinzip

我想将未来的读者指向解释此问题的以下链接。 http://libcwd.sourceforge.net/reference-manual/group__enable__glibcxx__debug.html

这是GLIBCXX_DEBUG标志文档的链接。它陈述了以下重要观点。

  • &#34;请注意,此标志会更改标准类模板(如std :: vector)的大小和行为,因此,如果没有实例化,则只能链接使用调试模式编译的代码和不使用调试模式编译的代码在两个翻译单元之间传递一个容器。&#34;

  • &#34;何时使用

    如果您怀疑与迭代器有关的问题,最好使用它。&#34;

现在,如果你查看最初发布的堆栈跟踪,崩溃是由于vector<testing::internal::ParameterizedTestCaseInfoBase*>发生的,因为gtest尝试使用begin()方法在此容器上获取​​迭代器。

在我的情况下,gtest lib编译为没有 GLICXX_DEBUG标志,但是我的测试代码编译为并带有此标志。当我没有这个标志编译时,测试代码就像一个魅力。