ここまでprintf関数を使ったテスト(C++ですからprintf関数ではなく、「<iostream>ライブラリとcoutストリーム」を使うのをお勧めしますが)の手順を説明しましたが、この方法ではテスト対象の増加に伴ってテスト・ケースも次第に増えてきます。
そうなると、各テスト結果の検証に多くの時間を要することになります。printf関数(あるいはcoutストリーム)で出力しているのは、関数/メソッドが返した値そのものであり、それが正しいか否かを目視でチェックしているのですから、テスト・ケースが数百数千ともなると正直うんざりしますし、チェック・ミスも起こるでしょう。単に値を出力するだけではいずれ限界となるのです。
そこで、テスト結果をもっと楽に検証するため、標準C++ヘッダ<cassert>に定義されたassertマクロを使ってみます。assertマクロは引数を1つ取り、その値が真(=0以外)であればそのまま次の行へと実行が進みますが、偽(=0)であった場合はそこでプログラムが停止します。
テスト・コード「abs_math_test.cpp」を以下のコードに差し替えます。
#undef NDEBUG
#include <cassert>
#include "abs_math.h"
using namespace std;
void abs_compare_test() {
/* 0 を返すケース*/
assert( 0 == abs_compare( 2, 2));
assert( 0 == abs_compare( 2,-2));
assert( 0 == abs_compare(-2, 2));
assert( 0 == abs_compare(-2,-2));
/* 1 を返すケース*/
assert( 1 == abs_compare( 3, 2));
assert( 1 == abs_compare( 3,-2));
assert( 1 == abs_compare(-3, 2));
assert( 1 == abs_compare(-3,-2));
/* -1 を返すケース*/
assert( -1 == abs_compare( 2, 3));
assert( -1 == abs_compare( 2,-3));
assert( -1 == abs_compare(-2, 3));
assert( -1 == abs_compare(-2,-3));
}
int main() {
abs_compare_test();
return 0;
}
assertマクロは、シンボル「NDEBUG」が定義されていると、コンパイル時に「assert(……);」という記述そのものがソース・コードに書かれていないのと同じになります。Visual Studioのプロジェクト・プロパティのデフォルト設定では、Releaseモードだと「NDEBUG」が定義されているため、Releaseモードでコンパイルされた際のテスト・コードはまったく機能しなくなってしまいます。そこでReleaseモードでもテストできるよう、テスト・コードの1行目に「#undef NDEBUG」を追加しました。
「assert」に続く丸カッコの中には「正しい結果が得られたら真となる式」を記述します。
これをビルドして実行してみましょう。すべてのテストが成功すれば、Releaseモードでは次のような結果となります。
何も出力されないことが全テスト成功の証しというわけです。試しに、テスト対象であるabs_compare関数が常に0を返すようなバグをわざと混入させ、Releaseモードで再テストすると、次のような結果になります。
このように、assertマクロによるテストに失敗した式とソース名そして行番号が出力されます。ちなみにDebugモード実行では次のようになります。
このダイアログの[再試行]ボタンをクリックすると、assertマクロによるテストに失敗した行で、実行にブレイクがかかった状態にすることができます。次の画面は実際にブレイクがかかったIDEの例です。
assertマクロを使ったテストだと、「正しく動いていれば真となる式」を並べるだけですし、実行結果の検証作業を一切必要としないので実装(あるいは修正)とテストをリズミカルに反復することができます。
しかしながらこの手法にも問題がないわけではありません。テストに失敗すると、それ以降のテストを行わずに終了してしまうので、そのテスト・ケースが成功するまで次のテストが行えません。複数のテスト項目を効率よく実行したいならテストの順序を手作業で並べ替えなくてはなりません。
成功/失敗にかかわらず全テスト・ケースを実行、あるいは全テスト・ケースの中から選択したものだけを実行し、失敗したケースのリストが一度に得られるなら、より効率的な実装/テストが行えることでしょう。次回はこのような要求に応えるべく作られたテスト環境「UnitTest Framework」を紹介します。
Copyright© Digital Advantage Corp. All Rights Reserved.