Boost logo

Boost Test Library: Test Execution Monitor

Introduction
Benefits
Example
Compilation
Test/Example Programs
Rationale
Design

Also see: Unit Test Framework

Introduction

Boost Test Library の Test Execution Monitor はmain()関数を提供し、その中でユーザの作成したtest_main() 関数を呼び出す。ライブラリの提供するmain()関数によって、ユーザは面倒なエラー検出・報告作業から解放される。Test Execution Monitor は、極めてシンプルなテストプログラムや既存の製品コード内の不具合を見つけ出す際の使用を意図している。 (非テスト用の)製品プログラムをモニタするのには、Program Execution Monitor の方が適している。 複雑なテストプログラム にはUnit Test Framework が適している。

Benefits

The Test Execution Monitor プログラムテストの簡単な枠組を提供する。reference to the top

Example

この例では、add()関数に対するエラーの検知・報告の6つの異なる方法を示している。

#include <boost/test/test_tools.hpp>

int add( int i, int j ) { return i+j; }

int test_main( int, char *[] )             // note the name!
{
    // six ways to detect and report the same error:
    BOOST_CHECK( add( 2,2 ) == 4 );        // #1 エラーが起きても継続する
    BOOST_REQUIRE( add( 2,2 ) == 4 );      // #2 エラーの際に例外を発生する
    if( add( 2,2 ) != 4 )
      BOOST_ERROR( "Ouch..." );            // #3 エラーが起きても継続する
    if( add( 2,2 ) != 4 )
      BOOST_FAIL( "Ouch..." );             // #4 エラーの際に例外を発生する
    if( add( 2,2 ) != 4 ) throw "Oops..."; // #5 エラーの際に例外を発生する

    return add( 2, 2 ) == 4 ? 0 : 1;       // #6 エラーコードを返す
}

Approach #1 BOOST_CHECK を使うと、失敗した旨、ソースファイル名、行番号を含むエラーメッセージをstd::coutに出力する。また、エラーカウントをインクリメントし、プログラム終了時にエラーカウントがTest Execution Monitorによって自動的に表示される。

Approach #2 BOOST_REQUIRE は#1と似ているが, エラーを出力した後で例外を発生し、 それをTest Execution Monitorがキャッチする点が異なる。 このアプローチは明確なテストプログラムを書くにあたり、発生したエラーが深刻でなものでこれ以上テストを継続できないようなときに適している。 BOOST_REQUIRE は、C++ Standard Library のマクロと異なり常に生成されており、検知したエラーをTest Execution Monitor に統一形式で報告する処理に繋げる。

Approaches #3 and #4 はそれぞれ#1 and #2 に似ているが、エラー検出コードを別に記述する。これはテストを行う条件から、失敗の理由がはっきりわからない場合に便利である。

Approach #5 例外を発生し、それがTest Execution Monitorによってキャッチされる。このアプローチは、ライブラリ内にあるなしにかかわらず、製品とテストコードの両方に適している。例外をキャッチした際に表示されるエラーメッセージは、その例外がstd::exceptionから派生している場合、またはchar*、std::stringである場合に最も重要である。

Approach #6 は呼び出し側にエラーを通知するのに返り値を使用する。 このアプローチは特に、test tools libraryを使った既存のテストコードを統合する際に適している。これはBoost Program Execution Monitor または Test Execution Monitor ライブラリでも十分動作し、それらの元で既存のコードを実行するのに非常に便利であるが、多くのC++に熟達した人達はエラー報告に例外を使用するのを好む。 reference to the top

The Test Execution Monitor compilation

The Test Execution Monitor は個別のライブラリとして提供されているので、コンパイル後にテストプログラムとリンクする必要がある。Boost Test Library のソースディレクトリに配置されている以下のファイルによりこのコンポーネントは構成されている。

execution_monitor.cpp
test_tools.cpp
unit_test_log.cpp
unit_test_parameters.cpp
unit_test_monitor.cpp
unit_test_result.cpp
unit_test_suite.cpp
test_main.cpp

Test Execution Monitorを構成するファイルをすべて、作成するテストモジュールに取り込むことも可能である。その際には<boost/test/included/test_exec_monitor.hpp> を使う。

Example and Test Programs

test_exec_example.cpp
test_exec_fail1.cpp
test_exec_fail2.cpp
test_exec_fail3.cpp
test_exec_fail4.cpp

reference to the top

Rationale

テストプログラムはどのようにしてエラーを報告するのがよいか。わかりやすいのがエラーメッセージを表示することである。

if( something_bad_detected )
  std::cout << "something bad has been detected" << std::endl;

これだと実行する毎に出力内容を検査し、エラーが起きたかどうかを判断しなければならない。テストプログラムは回帰テストとして何度も実行されるものなので、人間が出力を見てエラーを検出するのは時間がかかり過ぎるし信頼性に欠ける。これに対しGNU/expectのようなテストフレームワークは、エラーの検出を自動的に行うことができるが、簡単なテストを行う際には手間がかかり過ぎる。

エラーを報告するより簡単な方法は、テストプログラムが満足いくように終了した場合EXIT_SUCCESS(通常0)を返す、エラーを検出した場合EXIT _FAILUREを返すことである。これだと簡単な回帰テストスクリプトで、曖昧さのない自動エラー検出を行うことができる。HTMLテーブルの作成やメールによる警告の通知などのより適切な処理をスクリプトによって実現でき、実際のC++テストプログラムを変更せずに思い通りの修正を行うことができる。

テストプログラムがEXIT_SUCCESSまたはEXIT_FAILUREを返すという考えを基にしたテストルールは、いかなる支援ツールも必要としない。つまり、C++ 言語と標準ライブラリで充分なのである。また一方で、プログラマが覚えておかなければならないのが、すべての例外を漏らさずキャッチし、非ゼロ値を返してプログラムを終了させなければならないということである。それに、テストコード向けに標準ライブラリのassert()マクロも使ってはならない。システムによっては、手動での操作が必要になるなど、望ましくない副作用を伴うからである。

Test Execution Monitor はこれらのタスクを自動化してくれるが、プログラマはそれを無視して0を返り値とするテストを作成しがちである。

Design

The Boost Test Library Design ドキュメントはBoost Test Library コンポーネント間の関係を記述している。 reference to the top