4

比較関数に Boost::Test フレームワークを使用して単体テストを作成しています。テスト ケースごとに、一連の入力要素を作成し、それらをペアごとに比較して、各ペアの比較関数の戻り値を確認します。手動で書き出すか、関数を書くことができます。関数を書くことは単体テストには適していません。なぜなら、失敗したときに得られる情報が少なくなるためです。各チェックを手動で書き出すと、単体テストが非常に長くなります。そこで、チェックする要素を繰り返し処理するためにマクロを使用することにしました。次のようになります。

#define CHECK_NODE_LESS(less, more) do {\
        BOOST_CHECK_EQUAL(compareQueueUnderTest((less), (more)), true); \
        BOOST_CHECK_EQUAL(compareQueueUnderTest((more), (less)), false); \
} while (false)

#define CHECK_NODE_ORDER_ELEMENT(r, elem1, elem2) CHECK_NODE_LESS(elem1, elem2);

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \
        BOOST_PP_SEQ_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \
                        BOOST_PP_SEQ_REST_N(i, list))

#define CHECK_NODE_ORDER(nodes) \
        BOOST_PP_SEQ_FOR_EACH_I(CHECK_NODE_ORDER_INNER_LOOP, \
                        BOOST_PP_SEQ_TAIL(nodes), nodes)

部分的な順序付けではなく全体的な順序付けのテスト ケースではCHECK_NODE_LESS、適切な要素に対してマクロを使用して、順序付けられた要素をチェックしましたが、正常に動作しました。全順序付けのテスト ケースでは、CHECK_NODE_ORDERマクロを使用します。例えば:

CHECK_NODE_ORDER((node1)(rootNode1)(node2)(rootNode2));

現在、これはコンパイルされません。最初にテストしたのは、マクロをコメント アウトしCHECK_NODE_LESS、プリプロセッサを実行して何が生成されるかを確認することです。それは私が期待していたものでした:CHECK_NODE_LESS正しい要素のために呼び出されました. 次にCHECK_NODE_LESS、プリプロセッサを再導入して実行し、何が起こるかを確認しました。ブースト テストで使用したマクロのせいで結果は非常に醜いものでしたが、一部のマクロが展開されていないことがわかりました。

最後にCHECK_NODE_LESS、次のように変更したところ、正常に動作するようになりました。

#define CHECK_NODE_LESS(less, more) do {\
        BOOST_CHECK(compareQueueUnderTest((less), (more))); \
        BOOST_CHECK(!compareQueueUnderTest((more), (less))); \
} while (false)

BOOST_CHECK_EQUAL問題は、Boost Preprocessor ライブラリに他のマクロと一緒に使用するときに超過する反復制限があるか、コンパイラにプリプロセッサの深さの制限があることだと思います (私は Clang 3.4 を使用しています)。この制限とは何ですか?どうすればそれを増やすことができますか?

4

1 に答える 1

4

良い主。

Boost.Test に取り組んでいる人が、あなたがやろうとしていることを考慮していない可能性は十分にあります。問題はコンパイラの制限でBOOST_PP_SEQ_FOR_EACHはなく、再入可能ではなく、それをBOOST_CHECK_EQUAL使用することです。BOOST_CHECK_EQUALこのため、内部での使用BOOST_PP_SEQ_FOR_EACHはできません。BOOST_CHECK使用しないので動作しますBOOST_PP_SEQ_FOR_EACH

この回避策を提案します:

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \
    BOOST_PP_LIST_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \
                           BOOST_PP_SEQ_TO_LIST(BOOST_PP_SEQ_REST_N(i, list)))

ループを入れ子にするためだけにシーケンスをリストに変換するのはかなり見苦しいことは承知しています。私の弁護では、これは私が考えることができる最も醜いアプローチです。

于 2014-11-25T13:11:32.960 に答える