Google Test + Google Mockでのテスト
GoogleTestの使い方
簡単な使い方はGoogleのドキュメントを読めばなんとかなったので省略。
今回のやり方で困ったところやその解決方法を紹介する
導入
https://github.com/google/googletest
からcloneしてきて、自分のターゲット用にビルド。
Windowsターゲットだったのでmsvcディレクトリの中にあるslnを開き、
[プロパティ]->[C++]->[コード生成]やアーキテクチャを設定するいつもの儀式を行った後にビルド
GoogleTestのほうは
Release : gtest_main.lib / gtest.lib
Debug : gtest_maind.lib / gtestd.lib
となっているのに対し、なぜかGoogleMockはDebug用もRelease用も同一ファイル名で出力される罠があるので
ディレクトリを掘るかリネームして使う必要がある
実装
Dllのテスト
今回はテスト対象がDllだったため、そのままプロジェクトに入れることができなかった。
仕方ないので同一ソリューションにコンソールexeな別プロジェクトを作成、そちらに単体テストを実装する方針となった
最初はcppファイルをincludeする書き方をしていたが、あまりにもアレなのでやめた
また、dllにMockをinjectしたりする方法がわかんなかった(あるのかもわからなかった)ので、
テスト対象のソースを全てテストexeのプロジェクトに追加してテストを行った
Mock
Mock自体の作成はMOCK_METHODヘルパマクロを使えば簡単に作成可能だったが、
このMockをテスト対象のクラスに埋め込む方法で若干困った。
MockしたいクラスがSingletonだったのもあり、最終的にProxyで回避した
サンプル用にシンプルに手抜きされてるがこんな感じにして、TestクラスのSetUp()でcreateInstance自体を書き換えた
class Dependence
{
public:
static std::shared_ptr getInstance() {
if ( me_ == nullptr )
me_ = createInstance();
return me_;
}
static std::shared_ptr me_;
static std::function<std::shared_ptr(void)> createInstance;
}
非同期Callback関数のテスト
非同期だとローカル変数等がスコープアウトして死んでしまうため、テスト途中でアクセスバイオレーションが出る。
仕方ないのでWindowsAPIで同期待ちを行い回避したが、もっといいやり方がある気がしてならない
TEST_F(SampleTest, Sample) {
auto hEvent = CreateEvent(NULL, TRUE, FALSE, "TestEvent");
target_->asyncFunction( [&](auto& err) {
if ( err != nullptr ) {
FAIL() << "エラーが出たぞ : " << err->getMessage();
SetEvent(hEvent);
} else {
SUCCEED();
}
});
if (WaitForSingleObject(hEvent, TIMEOUT) == WAIT_TIMEOUT) {
FAIL() << "タイムアウト";
}
CloseHandle(hEvent);
}
Jenkins連携
出力されたexeに–gtest_output=xmlをつければJenkinsさんが読めるJUnit形式?のxmlが出るらしい
カバレッジ
どうも取れないもよう。別ツールも探してみたけどあまりいいのがなかった…
##まとめ
ざっとドキュメントを眺めるだけでかなり簡単に導入・利用できたのでおすすめ。