简体   繁体   English

Googletest 参数化测试崩溃

[英]Googletest Parametrized tests crash

I've just learned about value-parametrized unit tests in googletest and would like to use them in my project.我刚刚了解了googletest 中的值参数化单元测试,并希望在我的项目中使用它们。

I wrote a simple parametrized test.我写了一个简单的参数化测试。

Header:标题:

#include <gtest/gtest.h>

namespace EnsembleClustering {

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

} /* namespace EnsembleClustering */

Source:来源:

#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 */

Now, when I run googletest as usual, the program crashes without any output.现在,当我像往常一样运行 googletest 时,程序崩溃了,没有任何输出。 The gdb stack trace is 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 

Am I doing something wrong or is this a bug in googletest?我做错了什么还是这是googletest中的一个错误? Can you reproduce this error?你能重现这个错误吗?

EDIT: I am on Mac OS X 10.8.编辑:我在 Mac OS X 10.8 上。

From looking at the source code of gtest the only case if there are no parametrized tests available is on Windows using VC7.1 with disabled exceptions:从查看 gtest 的源代码来看,如果没有可用的参数化测试,唯一的情况是在使用 VC7.1 且禁用异常的 Windows 上:

// 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

So, you'll need to check how your MinGW was built and probably update it?那么,您需要检查您的 MinGW 是如何构建的并可能对其进行更新? And can you run the gtest unit tests to see if they execute the typed parameters test?您可以运行 gtest 单元测试来查看它们是否执行类型化参数测试吗?

More information on MinGW:有关 MinGW 的更多信息:

On their FAQ they report that when using MinGW the following compile option for building gtest is required: PATH/TO/configure CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin" .在他们的常见问题解答中,他们报告说在使用 MinGW 时需要以下编译选项来构建 gtest: PATH/TO/configure CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin"

Complete Example:完整示例:

#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();
}

I compiled this code using the following compiler call on Mac OS X 10.8:我在 Mac OS X 10.8 上使用以下编译器调用编译了这段代码:

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

Where GTEST_INCLUDE_DIR and GTEST_LIB_DIR are the path where header and library files are stored.其中GTEST_INCLUDE_DIRGTEST_LIB_DIR是存储头文件和库文件的路径。 When you compile and execute, what happens?当你编译和执行时,会发生什么?

Thanks @ChristianStaudt and @grundprinzip感谢@ChristianStaudt 和@grundprinzip

I would like to point future readers to following link that explains this problem.我想向未来的读者指出以下解释此问题的链接。 http://libcwd.sourceforge.net/reference-manual/group__enable__glibcxx__debug.html http://libcwd.sourceforge.net/reference-manual/group__enable__glibcxx__debug.html

This is a link to the documentation for GLIBCXX_DEBUG flag.这是 GLIBCXX_DEBUG 标志文档的链接。 It states the following important points.它陈述了以下要点。

  • "Note that this flag changes the sizes and behavior of standard class templates such as std::vector, and therefore you can only link code compiled with debug mode and code compiled without debug mode if no instantiation of a container is passed between the two translation units." “请注意,此标志更改了标准类模板(例如 std::vector)的大小和行为,因此,如果在两个翻译之间没有传递容器的实例化,则您只能链接使用调试模式编译的代码和不使用调试模式编译的代码单位。”

  • "When to use it “什么时候用

    It is a good idea to use this if you suspect problems related to iterators."如果您怀疑与迭代器相关的问题,最好使用它。”

Now, if you look at the stack trace posted originally, the crash happens due to vector<testing::internal::ParameterizedTestCaseInfoBase*> as gtest tries to get an iterator on this container, using begin() method.现在,如果您查看最初发布的堆栈跟踪,会发现崩溃是由于vector<testing::internal::ParameterizedTestCaseInfoBase*>因为 gtest 尝试使用 begin() 方法在此容器上获取​​迭代器。

In my case, gtest lib was compiled without GLICXX_DEBUG flag, but my test code was compiled with this flag.在我的例子中,gtest lib 是在没有GLICXX_DEBUG 标志的情况下编译的,但是我的测试代码是这个标志编译的。 The test code worked like a charm when I compiled without this flag.当我在没有这个标志的情况下编译时,测试代码就像一个魅力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM