2

我们已经开始将 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,这样如果成员变量未初始化,单元测试就可以捕获它。否则只有第一个单元测试有任何好处。

我更新到 boost 1.41,但问题没有解决。它确实在某些测试用例中对问题产生了一定的影响,但并没有达到所有测试都会正确失败的程度。

4

4 回答 4

2

如果您想要 ++paranoia,请尝试BOOST_TEST_RANDOM 。

于 2010-04-01T03:21:45.177 回答
2

不要为不同的测试重用测试用例名称。

相反,将它们称为:

test_select_base_instantiation_default_1

test_select_base_instantiation_default_2
于 2010-03-30T19:42:22.213 回答
1

那么提供的代码没有任何问题。

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

于 2010-03-30T20:50:21.910 回答
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);
}

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

于 2010-04-05T21:12:01.043 回答