本編では書ききれなかったことや、訂正なども含めて補足をしたいと思います。
値をパラメータ化したテスト
Boost.Test でも使えます。リファレンスはこちらです。(Boost.Test Example)
#include <boost/test/included/unit_test.hpp>
#include <boost/test/parameterized_test.hpp>
using namespace boost::unit_test;
//____________________________________________________________________________//
void free_test_function( int i )
{
BOOST_CHECK( i < 4 /* test assertion */ );
}
//____________________________________________________________________________//
test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
int params[] = { 1, 2, 3, 4, 5 };
framework::master_test_suite().
add( BOOST_PARAM_TEST_CASE( &free_test_function, params, params+5 ) );
return 0;
}
//____________________________________________________________________________//
こちらですが、自動でテストケースを認識・実行してくれる AUTO マクロがありません。
そのため、明示的に add する必要があります。
それはちょっと面倒臭い
ということで、簡単にマクロを用意してみました。
#include <boost/test/included/unit_test.hpp>
#include <boost/test/parameterized_test.hpp>
#define BOOST_AUTO_TEST_CASE_PARAM( function, begin, end ) \
BOOST_AUTO_TU_REGISTRAR( BOOST_JOIN(registrar, __LINE__) )( \
BOOST_PARAM_TEST_CASE(function, begin, end) )
void free_test_function( int i )
{
BOOST_CHECK( i < 4 /* test assertion */ );
}
int params[] = { 1, 2, 3, 4, 5 };
BOOST_AUTO_TEST_CASE_PARAM( &free_test_function, params, params+5 );

テストの中断
Boost.Test では REQUIRE 、Google Test では ASSERT フレーバーが失敗時にテストの中断をします。ただ、両者でこの中断の挙動が違うので補足をしておきます。
Boost.Test
void SubFunc(void)
{
BOOST_REQUIRE_EQUAL(0, 1);
BOOST_REQUIRE_EQUAL(1, 2);
}
BOOST_AUTO_TEST_CASE(Sub)
{
SubFunc();
BOOST_REQUIRE_EQUAL(2, 3);
}
void SubFunc(void)
{
ASSERT_EQ(0, 1);
ASSERT_EQ(1, 2);
}
TEST(Test, Sub)
{
SubFunc();
ASSERT_EQ(2, 3);
}
さて、ここで SubFunc(); 後のアサーションに到達するかが、ここでのお話です。
実際の出力を見てみましょう。
Boost.Test
Google Test
ご覧のように、Boost.Test は最初のアサーションの失敗で中断されていますが、Google Test は ASSERT_EQ(2,3); まで到達しています。
これは Google Test の中断が return 文を使った仕組みになっているからです。
なぜこのような実装になっているかは、こちらをご覧ください。
もし、SubFunc 内で失敗したときに、以降の処理を中断したい場合は以下のように書くことができます。
void SubFunc(void)
{
ASSERT_EQ(0, 1);
ASSERT_EQ(1, 2);
}
TEST(Test, Sub)
{
ASSERT_NO_FATAL_FAILURE( SubFunc() );
ASSERT_EQ(2, 3);
}

このように、SubFunc の失敗によりテストが中断します。
テスト以外での利用
Boost.Test や Google Test などテスティングフレームワークのアサーションは、ログに詳細な情報が出力されるので、普通の assert よりもとても有益な検証になります。通常、テストの検証として使用するこれらアサーションを、テスト以外の場所でも使おうという話です。
Boost.Test の場合
#define BOOST_TEST_NO_MAIN
#include <boost/test/included/unit_test.hpp>
int main(int , char**)
{
BOOST_CHECK_EQUAL(2, 3);
BOOST_REQUIRE_EQUAL(1, 2);
return 0;
}

特にログも出ずに死亡。うーん、残念。
Google Test の場合
#include <gtest/gtest.h>
void f(void)
{
ASSERT_EQ(1, 2);
}
int main(int, char**)
{
EXPECT_EQ(2, 3);
f();
return 0;
}

ログが出力されて正常終了しました。
また、GTEST_FLAG マクロを使って失敗時ブレークポイントを有効にすれば、より使い勝手が上がります。
int main(int, char**)
{
::testing::GTEST_FLAG(break_on_failure) = true; // break point を有効にする
EXPECT_EQ(2, 3);
f();
return 0;
}
終わり
ちょっとしたことでしたが、補足はこれで終わりです。また機会があればテスティングフレームワークについて書きたいと思います。
それでは、また来年!


0 件のコメント:
コメントを投稿