C++ の BDD-Style なテストフレームワーク igloo を使ってみた

C++ のテストフレームワーク igloo を使ってみました。

Loading...

igloo の特徴

ヘッダファイルのみなので導入が楽

iglooはヘッダファイルのみで構成されているため、テストフレームワーク自体のコンパイルが必要ないので導入が簡単でした。iglooのソースはgithubにあるので、

git submodule https://github.com/joakimkarlsson/igloo extlib/igloo

のようにして、"extlib/igloo" をインクルードパスに含めるようにするだけです。

Travis-CI などのCIサービスで使うのも簡単です。

BDDスタイルでテストを書ける

BDDスタイルでテスト/サブテストを書くことができます。これによりテストが構造化され、テストコードの見通しが良くなります。スタイルは以下の3つが使用できます。

  • Context/Spec
#include <igloo/igloo.h>
using namespace igloo;
 
Context(a_newly_started_game)
{
  Spec(should_have_an_empty_board)
   {
     Assert::That(game.Positions(), Has().All().EqualTo(EmptyPosition));
   } 
   Game game;
};
  • Describe/It
#include <igloo/igloo_alt.h>
using namespace igloo;

Describe(a_newly_started_game)
{
  It(has_an_empty_board)
  {
    Assert::That(game.Positions(), Has().All().EqualTo(EmptyPosition));
  } 

  Game game;
};
  • When/Then
#include <igloo/igloo_alt.h>
using namespace igloo;

When(a_new_game_is_started)
{
  Then(it_should_have_an_empty_board)
  {
    Assert::That(game.Positions(), Has().All().EqualTo(EmptyPosition));
  } 

  Game game;
};

もちろん、setUp/tearDownで各テストケースの前後に実行する処理を記述したり、SetUpContext/TearDownContextで当該Contextの最初と最後に1度だけ実行される処理を記述することもできます。

Constraint-Based Assert Model

igloo の assert は NUnit(NUnit 2.4) の Constraint-Based Assert Model に影響を受けたものが採用されています。

以下の様なフォーマットで記述します。

Assert::That(actual_value, <constraint expression>);

これだけだと何が嬉しいのかわかりづらいので、以下に例を示します。

Assert::That(result_a, Equals(0));   // That result_a equals 0.
Assert::That(result_b, Is().EqualTo(2)); // That result_b is equal to 2.

このように文法的にテストの意味がわかりやすくなります。

実際の使用例

igloo を実際に cpp-HyperLogLog で使ってみました。

使用例

ハマりどころ

基本的に単純な記述で書けるのですが、ハマったのが

(Describe|Context|When)の最後の}の後ろにセミコロンが必要

まぁ、実体はクラス定義であることを考えれば当然といえば当然ですが・・・

もう1点、Assert::That()がFailした際にファイル名、行番号が出力されるようにするには、Assert::That()に明示的にファイル名、行番号の情報を引数で渡す必要があります。

#define AssertThatEx(X,Y) Assert::That(X,Y,__FILE__, __LINE__)

上記のようなマクロで自動的にファイル名と行番号を渡してやると楽だと思います。

感想

以前まではCPPUnitを使っていたのですが、CPPUnit を使ったことがある方はわかると思いますが、CPPUnitはテストケースやテストランナーの記述がやや煩雑・冗長なのです。それによってテストの可読性が低下してテストのメンテナンスがツライ・・・ということになりがちです。

igloo は導入が楽で、かなり簡潔にテストを記述できると思います。サブテストによるテストの構造化や、Constraint-Based Assert Model によって可読性も向上するので、しばらく C++ のプロジェクトのテストには igloo を使っていきます。