Boost Unit测试内存重用,导致无法通过的测试

时间:2010-03-30 19:15:51

标签: c++ unit-testing memory boost callstack

我们已经开始将boost单元测试库用于大型现有代码库,并且我在单元测试错误传递时遇到了一些麻烦,似乎是由于堆栈上的内存重用。

以下是我的情况:

BOOST_AUTO_TEST_CASE(test_select_base_instantiation_default)  
{
    SelectBase selectBase();
    BOOST_CHECK_EQUAL( selectBase.getSelectType(), false);
    BOOST_CHECK_EQUAL( selectBase.getTypeName(_T(""));
    BOOST_CHECK_EQUAL( selectBase.getEntityType(), -1);
    BOOST_CHECK_EQUAL( selectBase.getDataPos(), -1);
}

BOOST_AUTO_TEST_CASE(test_select_base_instantiation_parameterized)  
{  
    SelectBase selectBase(true, _T("abc"));  
    BOOST_CHECK_EQUAL( selectBase.getSelectType(), false);  
    BOOST_CHECK_EQUAL( selectBase.getTypeName(_T("abc"));
    BOOST_CHECK_EQUAL( selectBase.getEntityType(), -1);
    BOOST_CHECK_EQUAL( selectBase.getDataPos(), -1);
}

第一次测试正确通过,初始化所有变量 第二个单元测试中的构造函数未正确设置EntityType或DataPosition,但单元测试已通过。我可以通过在第二个测试中在堆栈上放置一些变量来使它失败,如下所示:

BOOST_AUTO_TEST_CASE(test_select_base_instantiation_parameterized)  
{  
    int a, b;
    SelectBase selectBase(true, _T("abc"));  
    BOOST_CHECK_EQUAL( selectBase.getSelectType(), false);  
    BOOST_CHECK_EQUAL( selectBase.getTypeName(_T("abc"));
    BOOST_CHECK_EQUAL( selectBase.getEntityType(), -1);
    BOOST_CHECK_EQUAL( selectBase.getDataPos(), -1);
}

如果只有一个int,则只有EntityType CHECK_EQUAL失败,但如果有两个,则EntityType和DataPos都会失败,所以很明显这是在同一堆栈内存或某些内存上创建的变量的问题这样。

有没有一种很好的方法来清除每个单元测试之间的内存,或者我是否可能错误地使用库或编写错误的测试?任何帮助将不胜感激。

更新
Select base是一个简单的类,只有bool,int和CString成员变量。它是处理更复杂实现的状态的基类,因此它不访问任何全局变量或全局状态。

我需要的是一种在0xdeadf00d之类的调用之间设置内存的方法,这样如果一个成员变量未初始化,单元测试就可以捕获它。否则只有第一次单元测试有任何好处。

我更新到了增强版1.41,但问题没有解决。它确实在一些测试用例中对这个问题产生了影响,但是并没有达到所有测试都能正常失败的程度。

4 个答案:

答案 0 :(得分:2)

不要将测试用例名重用于不同的测试。

相反,请将它们称为:

test_select_base_instantiation_default_1

test_select_base_instantiation_default_2

答案 1 :(得分:2)

如果你想要++偏执,请尝试BOOST_TEST_RANDOM

答案 2 :(得分:1)

然后提供的代码没有任何问题。

您似乎正在访问SelectBase中的未初始化数据或其任何依赖项(如果有)。要么在SelectBase中访问全局状态,要么它自己实例化依赖项。两个人都气馁。

答案 3 :(得分:0)

我最终编写了一个函数,在每个测试用例后将对象设置为无效状态:

void unsetSelectBase(SelectBase selectBase) 
{
    selectBase.setSelectType(true);
    selectBase.getTypeName(_T("InvalidName"));
    selectBase.getEntityType(42);
    selectBase.getDataPos(2718);
}

BOOST_AUTO_TEST_CASE(test_select_base_instantiation_default)  
{
    SelectBase selectBase();
    BOOST_CHECK_EQUAL( selectBase.getSelectType(), false);
    BOOST_CHECK_EQUAL( selectBase.getTypeName(_T(""));
    BOOST_CHECK_EQUAL( selectBase.getEntityType(), -1);
    BOOST_CHECK_EQUAL( selectBase.getDataPos(), -1);
    unsetSelectBase(selectBase);
}


BOOST_AUTO_TEST_CASE(test_select_base_instantiation_parameterized)  
{  
    SelectBase selectBase(true, _T("abc"));  
    BOOST_CHECK_EQUAL( selectBase.getSelectType(), false);  
    BOOST_CHECK_EQUAL( selectBase.getTypeName(_T("abc"));
    BOOST_CHECK_EQUAL( selectBase.getEntityType(), -1);
    BOOST_CHECK_EQUAL( selectBase.getDataPos(), -1);
    unsetSelectBase(selectBase);
}

这会导致所有测试用例在未初始化任何成员变量时适当地失败。我想这只是另一个必要的手动设置/拆卸类型任务,因为框架不会清除内存。