Google Testを使う

GoogleのC++用のテストフレームワーク。これを使うと何が嬉しいのか
・出力がきれい
・デフォルトでいろんなコマンドラインをつけてくれる
・コマンドラインでテストの制御ができる
・パラレルで実行できる(多分)
・繰り返し実行して簡易計測ができる
・デステストができる

しかしGUIアプリの場合はテストは難しいのでここではスルー。テストはあくまで機能として分離がし易いものをテストする段階。付属のGoogleMockなどをつかって、Mockオブジェクトを作り分離させるために頑張る方法もあるのだろうがここではスルー。

実験

ここでは既存の自作テストプロジェクトをGoogleTestに置き換えていくことを想定。別に新規に追加しても良い。Windows, VS2013, C++/CLIプロジェクト

git submoduleで追加

ソリューションのフォルダで以下を実行して、googletestを持ってくる。べつにダウンロードしてもいい。

テストプロジェクトの設定

テストプロジェクトにgoogletestのソースコードを追加する。テストプロジェクトがなければコンソールアプリで作る。

まず、googletest\googletest\src\gtest-all.ccをプロジェクトのソースコードに追加。このファイルは必要なソースをincludeしてこのファイルだけで全部ビルドできる。

次にプロジェクトのインクルードパスに以下の2つを追加

これで準備が整ったのでmain.cpp(自分のファイル)にテストコードを書く。

InitGoogleTestは最初に書いたようにコマンドラインを処理してくれる。RUN_ALL_TESTSはこちらが定義したテストを実行する。今はまだ何も定義してない。

テストの定義

以下のように書く。

TESTマクロは2つの引数を取る。最初の引数はテストケースと呼ばれていて、テストを大きくカテゴライズしたもの、次の引数はそのカテゴリー内のテスト。1つのクラスをテストケースと考えてその中のメンバ関数をテスト名と考えてもいいかもしれない。

テストコード内でマクロを書く

テストコード内でテスト用のマクロを書く。これに引っかかるとテストに失敗するが、いろんな失敗のさせ方があるらしい。EXPECTは失敗しても続行の失敗(のはず)。ASSERTは失敗すると止める。

コマンドラインのチェック

ここで一旦コーディングをやめて、コマンドラインを試してみる。-hでヘルプを見れる。

–gtest_list_tests

オプション無しでテスト実行

GoogleTestをプロジェクトに追加しておくと、自分がテストするだけでなく、他人がプロジェクトの内容を知ることもできるし、実行ファイルを生成するので、どのように動くのかもわかって便利。

このようにテストをどんどん追加していくと、持つべきデータや初期化作業が共通化してくるので、これをFixtureと読んでおく。このFixture付きのテストがTEST_F。

TEST_F

以下の普通のTESTがあるとする。

これをTEST_Fに置き換えたのが以下。

TEST_Fの中でclassのインスタンスにアクセスできる。このクラスの初期化と終了処理はSetUpとTearDownのオーバーライドで行う。ちなみにこのクラスはテストごとに作られて、インスタンスは共通ではない。

フィルター

-gtest_filterでテストをフィルタできる。テストケースとテスト名は’.’ピリオドで区切る。ワイルドカードも使える。

powershellとリピートでトータル時間を計算する

フィルターでテストを指定し、リピートで繰り返し実行し、powershellのMeasure-Commandで時間を計算すれば、指定されたテストのみの実行時間を計算できるので、コードを変えたときの変化を見ることができる

パラレルで実行する

gtest-parallel(python2スクリプト)でパラレル実行ができるみたいなので試してみる。git submoduleや単にダウンロードしてインストールされたものとする。

デステスト

デステストとはアプリがちゃんと終了するか(クラッシュするか)をテストするツールである。

こられのマクロのMyExitはこのプロセスでは実行されない。同じ実行ファイルを内部引数で起動し(InitGoogleTestで処理される)そのプロセスで実行される。実行された結果の出力と最後に指定された正規表現を比較してテストし、EXPECT_EXITの場合は二番目にに指定された述語(関数オブジェクト)をExitCodeを引数に呼ぶ。これがfalseを返したり、MyExitが実際に終了しなかったりするとテストはエラーを報告する。

Leave a Reply

Your email address will not be published. Required fields are marked *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)