2012年4月24日火曜日

C++のテストフレームワーク Boost.Testを試してみた

はじめに 
これまでCppUnit, googletestとC++のテストフレームワークを試してきました。
今回はBoost.Testを試してみます。
実行環境は、Mac OS X(ver. 10.7.3), Boost(var. 1.49.0)です。

ダウンロードとインストール
Macユーザーなら、Macportsでインストールすることができます。
$ sudo port install jam
$ sudo port install boost
インストール後は、環境変数を設定しておきましょう。
Boostのインストールに関しては、こちらのサイトさんが大変参考になりました。

テストプログラムを書いてみる
今回もテスト対象のプログラムはFizzBuzz問題としました。 
//FizzBuzz.h
#include <string>
 
class FizzBuzz {
  public:
    std::string Print(int n);
};
//FizzBuzz.cpp
#include <sstream>
#include "FizzBuzz.h"
 
using namespace std;
 
string FizzBuzz::Print(int n) {
  ostringstream sout;
  if(n % 3 == 0) sout << "Fizz";
  if(n % 5 == 0) sout << "Buzz";
  if(n % 3 != 0 && n % 5 != 0) sout << n;
  return sout.str();
}
Boost.Testではテストプログラムは以下のように書くと良いみたいです。
//FizzBuzzTest.cpp

//Macの場合は以下の記載がが必要(後述)
#define BOOST_TEST_DYN_LINK 
//Main関数を用意する必要がなくなる
#define BOOST_TEST_MAIN 
//テスト名を定義する
#define BOOST_TEST_MODULE FizzBuzzTest 
#include <boost/test/unit_test.hpp>
#include "FizzBuzz.h"

//Fixture
struct FizzBuzzFixture {
    FizzBuzzFixture() {
        this->fb_ = new FizzBuzz();
    }
    ~FizzBuzzFixture() {
        delete this->fb_;
    }
    FizzBuzz* fb_;
};

//一連のテスト群にFixtureを適用する場合は下記のように書く
//第一引数がテスト群の名前、第二引数が使用するFixtureの名前
BOOST_FIXTURE_TEST_SUITE(FizzBuzz, FizzBuzzFixture)
 
BOOST_AUTO_TEST_CASE( testFizz )
{
    BOOST_CHECK_EQUAL( "Fizz", fb_->Print(3) );
}
 
BOOST_AUTO_TEST_CASE( testBuzz )
{
    BOOST_CHECK_EQUAL( "Buzz", fb_->Print(5) );
}
 
BOOST_AUTO_TEST_CASE( testFizzBuzz )
{
    BOOST_CHECK_EQUAL( "FizzBuzz", fb_->Print(15) );
}
 
BOOST_AUTO_TEST_CASE( testOther )
{
    BOOST_CHECK_EQUAL( "2", fb_->Print(2) );
}
BOOST_AUTO_TEST_SUITE_END();

Fixtureに関しては、上記のSuiteに適用する以外にも、
BOOST_GLOBAL_FIXTURE(fixure_name)
とすることで全体に適用できたり、
BOOST_FIXTURE_TEST_CASE( test_case_name, fixture_name )
{
    //test
}
とすることで、個別に適用することができるみたいです。
#詳しくはこちらを参照してください。
また、
#define BOOST_TEST_DYN_LINK
に関してですが、Macの場合、これを書かずにコンパイルしようとすると以下のようなエラーが出ます。
Undefined symbols for architecture x86_64:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Macは静的リンクがサポートされていないことが原因みたいです。
こちらを参考にさせて頂きました。

コンパイルは以下で行います。
$ g++ FizzBuzz.cpp FizzBuzzTest.cpp -o FizzBuzzTest -lboost_unit_test_framework

テストプログラムを実行してみる
まず、普通に実行してみると以下のような出力となります。
$ ./FizzBuzzTest
Running 4 test cases...

*** No errors detected

うーん、シンプルすぎる…と思ったのですが、 Boost.Testの場合色々オプションを指定することができるみたいです。
$ ./FizzBuzzTest --report_level=detailed --show_progress=yes --build_info=yes

0% 10 20 30 40 50 60 70 80 90 100%
|----|----|----|----|----|----|----|----|----|----|
Running 4 test cases...
Platform: Mac OS
Compiler: GNU C++ version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
STL : GNU libstdc++ version 20070719
Boost : 1.49.0
***************************************************

Test suite "FizzBuzzTest" passed with:
4 assertions out of 4 passed
4 test cases out of 4 passed

Test suite "FizzBuzz" passed with:
4 assertions out of 4 passed
4 test cases out of 4 passed

Test case "testFizz" passed with:
1 assertion out of 1 passed

Test case "testBuzz" passed with:
1 assertion out of 1 passed

Test case "testFizzBuzz" passed with:
1 assertion out of 1 passed

Test case "testOther" passed with:
1 assertion out of 1 passed

前回googletestに関する記事を書きましたが、 テストの記述量も記載方法もBoost.Testとgoogletestではそこまで大きくは異なってない印象を受けるのでどちらがいいかは各々のお好みでよさそうです。
私は出力がgoogletestの方が好みなので、googletestを利用しています。

相変わらず大した内容でもありませんが、今回のソースコードはこちらにまとめましたので、参考にどうぞ。

0 件のコメント:

コメントを投稿