2

ブーストユニットテストライブラリを既存の大規模なコードベースに使用し始めましたが、スタック上のメモリの再利用が原因と思われる、ユニットテストが誤って合格するという問題が発生しました。

これが私の状況です:

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

最初のテストは正しく合格し、すべての変数が初期化されました。
2番目の単体テストのコンストラクターはEntityTypeまたはDataPositionを正しく設定しませんでしたが、単体テストは合格しました。次のように、2番目のテストでいくつかの変数をスタックに配置することで、失敗させることができました。

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が1つしかない場合は、EntityType CHECK_EQUALのみが失敗しますが、2つある場合は、EntityTypeとDataPosの両方が失敗するため、これが同じスタックメモリなどで作成されている変数の問題であることは明らかです。

各単体テストの間にメモリをクリアする良い方法はありますか、それともライブラリを誤って使用したり、悪いテストを書き込んだりする可能性がありますか?どんな助けでもいただければ幸いです。

更新:
Select baseは、bool、int、およびCStringメンバー変数のみを持つ単純なクラスです。これは、より複雑な実装の状態を処理するための基本クラスであるため、グローバル変数またはグローバル状態にアクセスしません。

私が必要としているのは、呼び出し間のメモリを0xdeadf00dのようなものに設定する方法です。これにより、メンバー変数が初期化されていない場合、単体テストでそれをキャッチできます。それ以外の場合は、最初の単体テストのみが効果を発揮します。

Boost 1.41にアップデートしましたが、問題は解決しませんでした。一部のテストケースでは問題に多少影響しましたが、すべてのテストが適切に失敗するほどではありませんでした。

4

4 に答える 4

2

テストケース名を別のテストに再利用しないでください。

代わりに、次のように呼びます。

test_select_base_instantiation_default_1

test_select_base_instantiation_default_2
于 2010-03-30T19:42:22.213 に答える
2

++パラノイアが必要な場合は、BOOST_TEST_RANDOMを試してください。

于 2010-04-01T03:21:45.177 に答える
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);
}

これにより、メンバー変数が初期化されていない場合、すべてのテストケースが適切に失敗します。フレームワークはメモリをクリアしないので、これは必要なもう1つの手動セットアップ/分解タイプのタスクだと思います。

于 2010-04-05T21:12:01.043 に答える