boost::unit_test_framework でユニットテスト

ちょっと仕事で簡単な C++ コードとそのテストコードを作る必要ができたので、boost の unit_test_framework を試してみることにしました。

準備

最初に試した環境は Gentoo なので、emerge boost すれば一番楽チンなんですが、あとで別の環境に持っていく必要があったので、テスト対象のコードがあるディレクトリの下にそのまま置くことにしました。

http://www.boost.org/users/download/ からソースコードの tar 玉をもらってきて、展開します。

$ tar xjvf boost_1_37_0.tar.bz2

boost のライブラリのほとんどはヘッダをインクルードするだけで使用可能ですが、いくつかの例外のライブラリは事前にビルドが必要です。で、test ライブラリはその例外に含まれてます。

$ cd boost_1_37_0
$ ./configure --with-libraries=test
$ make

全部ビルドすると結構な時間がかかるので、test ライブラリだけ make します。今回は make install はしません。

boost_1_37_0/bin.v2/libs/test/build/gcc-3.2.3/release/link-static/threading-multi/libboost_unit_test_framework-gcc32-mt-1_37.a ができていることを確認します。

ソースコード

たとえば、こんなコードがテスト対象だとします。昔に書いた goban.scm の一部を C++ で書いてみた、つもり。

goban.hpp
class Point {
public:
  int x, y;
  Point(int x, int y);
  Point up();
  Point down();
  Point left();
  Point right();
};
goban.cpp
#include "goban.hpp"

Point::Point(int x, int y) : x(x), y(y) {}

Point Point::up() {
  return Point(x, y - 1);
}

Point Point::down() {
  return Point(x, y + 1);
}

Point Point::left() {
  return Point(x - 1, y);
}

Point Point::right() {
  return Point(x + 1, y);
}

テストコードはこんなふうになります。

goban-test.cpp

2009-02-15 追記 BOOST_AUTO_TEST_CASE を使って書き換えました。

#include "goban.hpp"
#include <boost/test/unit_test.hpp>

using namespace boost::unit_test_framework;

void point_test() {
  Point p = Point(3, 4);

  BOOST_CHECK_EQUAL(p.x, 3);
  BOOST_CHECK_EQUAL(p.y, 4);

  Point pu = p.up();
  Point pd = p.down();
  Point pl = p.left();
  Point pr = p.right();

  BOOST_CHECK_EQUAL(pu.x, p.x);
  BOOST_CHECK_EQUAL(pu.y, p.y - 1);

  BOOST_CHECK_EQUAL(pd.x, p.x);
  BOOST_CHECK_EQUAL(pd.y, p.y + 1);

  BOOST_CHECK_EQUAL(pl.x, p.x - 1);
  BOOST_CHECK_EQUAL(pl.y, p.y);

  BOOST_CHECK_EQUAL(pr.x, p.x + 1);
  BOOST_CHECK_EQUAL(pr.y, p.y);
}

test_suite* init_unit_test_suite(int argc, char* argv[]) {
  test_suite* test = BOOST_TEST_SUITE("goban test");
  test->add(BOOST_TEST_CASE(&point_test));
  return test;
}

main はリンクするライブラリで定義されています。

コンパイル

$ g++ -Iboost_1_37_0 \
      -Lboost_1_37_0/bin.v2/libs/test/build/gcc-4.1.2/release/link-static/threading-multi \
      goban.cpp goban-test.cpp \
      -static -lboost_unit_test_framework-gcc41-mt-1_37 \
      -o goban-test

-L が長くてうぜーっすね。LD_LIBRARY_PATH に追加すればいいんでしたっけ?