例えば、MFCでカウンタ・クラス(=Counterクラス)を実装することを考えてみましょう。
この図の構成でカウンタ・クラスをMFCのSDI形式のアプリケーションに仕立てると、次の画面のような外観のアプリケーションとなりました。
このときDocument側は、次のようなコードとなります。
#include "Counter.h"
class CounterDoc : public CDocument {
private:
Counter body_;
public:
void incr() { body_.incr(); UpdateAllViews(0); }
void clear() { body_.clear(); UpdateAllViews(0); }
int get() const { return body_.get(); }
……省略……
}
そしてView側は、次のようになります。
……省略……
// CounterViewクラスのメッセージ・ハンドラ
void CounterView::OnUpdate(CView*, LPARAM, CObject*) {
CString count;
count.Format(_T("%d"), GetDocument()->get());
GetDlgItem(IDC_COUNT)->SetWindowText(count);
}
// [increment]ボタンが押されたときの処理
void CounterView::OnBnClickedIncr() {
GetDocument()->incr();
}
// [clear]ボタンが押されたときの処理
void CounterView::OnBnClickedClear() {
GetDocument()->clear();
}
……省略……
このアプリケーションに手を加え、単体テストをアプリケーション内にねじ込んでみましょう。この方法を使えば、実際のアプリケーションに近い環境でのテストが行え、ロジックのテストとUIの実装とを同時進行させることができます。
まず、メニュー・バーの項目として[TEST]を追加し、そのクリック・メッセージ・ハンドラとしてOnTestメソッドを追加します。テスト・コードは、前章のCounterTest.cppファイルをそのまま(コピーして)流用します。OnTestメソッド内の実装は、Main.cppファイルの内容にほんの少し手を加えたものです。
……省略……
// メニュー・バーで[TEST]が選択された
void CounterView::OnTest() {
// イベント・マネージャとテスト・コントローラを生成する
CPPUNIT_NS::TestResult controller;
// テスト結果収集リスナをコントローラにアタッチする
CPPUNIT_NS::TestResultCollector result;
controller.addListener( &result );
// 「.」で進行状況を出力するリスナをアタッチする
CPPUNIT_NS::BriefTestProgressListener progress;
controller.addListener( &progress );
// テスト・ランナーにテスト群を与え、テストする
CPPUNIT_NS::TestRunner runner;
runner.addTest(
CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
runner.run( controller );
// テスト結果を文字列ストリームに流し入れ、
std::ostringstream stream;
stream << "************ テスト開始 ************\n";
CPPUNIT_NS::CompilerOutputter outputter( &result, stream);
outputter.write();
stream << "************ テスト終了 ************\n";
// 得られた文字列をTRACEマクロで出力する
TRACE(stream.str().c_str());
}
アプリケーションを実行し、メニュー・バーの[TEST]をクリックすると、アプリケーション内に埋め込んだテストが実行され、テスト結果がIDEの出力ペインに表示されます。
次回は、.NET Frameworkに対応した単体テスト・フレームワークの1つである「NUnit」を紹介し、NUnitによるC++コードのテストを試みます。
Copyright© Digital Advantage Corp. All Rights Reserved.