2012年3月27日火曜日

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

はじめに
前回の記事ではテスト環境を構築するため、C++用テストフレームワークCppUnitを試しました。今回は、こちらもC++用テストフレームワークとして有名なgoogletestを試してみます。

googletestを使う準備をする
準備は以下のコマンドから。
cmakeが必要なので、あらかじめ入れておく必要があります。


$ svn checkout http://googletest.googlecode.com/svn/trunk/ googletest
$ cd googletest
$ mkdir mybuild
$ cd mybuild/
$ cmake ..
$ make
一連のコマンドで、libgtest.a, libgtest_main.aが出来上がります。
  
テストプログラムを書いてみる
CppUnitとの比較のため、今回もテスト対象のプログラムは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();
}

次にテストプログラムを書きます。
googletestの場合には、出来上がったlibgtest_main.aを利用することで、Main関数を作成しなくても良いみたいです。
//FizzBuzzTest.cpp
#include "FizzBuzz.h"
#include "gtest/gtest.h"
 
class FizzBuzzTest : public ::testing::Test {
 protected:
 
  FizzBuzzTest() {
  }
 
  virtual ~FizzBuzzTest() {
  }
 
  virtual void SetUp() {
    this->fb_ = new FizzBuzz();
  }
 
  virtual void TearDown() {
    delete this->fb_;
  }
 
  FizzBuzz* fb_;
};
 
TEST_F(FizzBuzzTest, testFizz) {
  EXPECT_EQ("Fizz", fb_->Print(3));
}
 
TEST_F(FizzBuzzTest, testBuzz) {
  EXPECT_EQ("Buzz", fb_->Print(5));
}
 
TEST_F(FizzBuzzTest, testFizzBuzz) {
  EXPECT_EQ("FizzBuzz", fb_->Print(15));
}
 
TEST_F(FizzBuzzTest, testOther) {
  EXPECT_EQ("2", fb_->Print(2));
}

コンストラクタとデストラクタ、SetUpとTearDownは、テストケースを実行する前後の処理を定義する関数です。コンストラクタ→SetUp→テスト関数→TearDown→デストラクタの順に呼び出されます。使い分けとしては、例外処理を扱う場合はSetUp/TearDownを使うべきとのこと(詳細はこちら)。
前回の記事と同様に、3を引数としたときには"Fizz"を、5を引数にしたときには"Buzz"を、15を引数にしたときには "FizzBuzz"を、2を"2"を出力することを確認する4つのテストケースを作成しました。

$ g++ -I{$GOOGLE_TEST_DIR}/include FizzBuzz.cpp FizzBuzzTest.cpp {$GOOGLE_TEST_DIR}/mybuild/libgtest.a {$GOOGLE_TEST_DIR}/mybuild/libgtest_main.a -o FizzBuzzTest
$ ./FizzBuzzTest
Running main() from gtest_main.cc

[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from FizzBuzzTest
[ RUN      ] FizzBuzzTest.testFizz
[       OK ] FizzBuzzTest.testFizz (0 ms)
[ RUN      ] FizzBuzzTest.testBuzz
[       OK ] FizzBuzzTest.testBuzz (0 ms)
[ RUN      ] FizzBuzzTest.testFizzBuzz
[       OK ] FizzBuzzTest.testFizzBuzz (0 ms)
[ RUN      ] FizzBuzzTest.testOther
[       OK ] FizzBuzzTest.testOther (0 ms)
[----------] 4 tests from FizzBuzzTest (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 4 tests.

できました!
ここでは表現できていないのですが、実際にはテストが通れば緑文字、そうでなければ赤文字でコンソール上に結果が出ます。

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

CppUnitとの比較
ちょっと試しただけなので比較するほど使いこめてはいないのですが、
  • googletestの方が記述量が少ない
  • googletestのほうがアサーションが豊富
    CppUnitが10個程度なのに比べてgoogletestは40個以上?
    (数えてみたのですが多かったので途中で断念しました。)
  • 成功で緑、失敗で赤表示が嬉しい
と感じたので、この2つの中で選ぶのなら、個人的にはgoogletestをお勧めします。  

さいごに
今回参考にしたサイトは以下です。
http://d.hatena.ne.jp/snaka72/20110720
http://opencv.jp/googletestdocs/index.html

0 件のコメント:

コメントを投稿