読者です 読者をやめる 読者になる 読者になる

hellkite 日記と雑記とメモ。

Shiki Kazamaの駄文と音楽と、時々技術な感じ

VisualC++上でNUnitの設定、実行までのメモ

VC

スポンサーリンク


単体テストフレームワークで有名なものといえば、xUnitと呼ばれるツール群。VisualC++では、.NetFrameworkを使っているので、.NetFramework用のNUnitを使用することが出来ます。
連載 C++開発者のための単体テスト入門:第3回 C++アプリケーションの効率的なテスト手法(NUnit編) (3/4) - @IT


リンク先では、標準C++のテストでもNUnit使っていますね。.NetFrameworkでも、同じ方法でテストすることができます。

前準備

NUnitを使うためには、公式HPからインストーラをダウンロードしてインストールする必要があります。
NUnit - Home


ダウンロードページからダウンロードして、インストールするだけです。

プロジェクトの準備

NUnitを使いたいプロジェクトにnunit.frameworkを登録します。
プロジェクト > プロパティから、新しい参照の追加の.Netタブに「unit.framework」を追加してください。

単体テスト用のクラスを作成

単体テスト用のクラスを追加します。クラス名は「TargetClassNameTest」みたいに、テスト対象のクラス名を入れておくのが一般的(?)みたいです。
単体テスト用のクラスのヘッダと実装ファイルは以下のようにします。

// TargetClassNameTest.h
#pragma once

using namespace System;
using namespace NUnit::Framework;

#include "TargetClassName.h"

using namespace TargetClassName;

[TestFixture]
ref class TargetClassNameTest : AssertionHelper
{
public:
        TargetClassNameTest(void);

        [SetUp]         void setUp();
        [TearDown]      void tearDown();

        [Test]          void testTargetFunction();
};
// TargetClassNameTest.cpp
#include "StdAfx.h"
#include "TargetClassNameTest.h"
#include "TargetClassName.h"


TargetClassNameTest::TargetClassNameTest(void)
{
}

void TargetClassNameTest::setUp() {
        // テストケース直前に呼ばれる処理
}

void TargetClassNameTest::tearDown() {
        // テストケース実行直後に呼ばれる処理
}

// 以降はテストケースの実行内容
void TargetClassNameTest::testTargetFunction() {
        Expect(::TargetClassName::targetFunction("SampleData"), EqualTo("Correct Data"));
}


テスト用のコードを書いていきます。Expectの第2引数に指定できるものは、公式のドキュメントをあさってください。
上のコードは雛形として登録しておくといいかもしれないですね。

単体テストの実行

単体テスト用のクラスと、テスト対象のクラスの準備ができたら、ビルドします。
ビルドしたら、すべてのプログラムからNUnitを起動します。起動したら、ビルドしてできた.dllを選択して読み込みます。
あとはRUNを押すだけで、テストが実行されます。


以後は、プログラムを変更するたびに、NUnitのRunを押すだけです。
ショートカットを使うなら、VisualC++でF7を押してビルド、次にAlt+TabでNUnitに移ってF5を押す、というのを癖にしておくといい感じ。

まとめ

簡単に何度もテストを行うことができる環境は、コードを頻繁に書き換えるプログラミングでは必須です。設定もそんなに難しくないし、使う価値がある・・・というか、使わなくてどうするの?という感じ。
テストコードを書くのは大変だけど・・・テストコードのパラメータはあらかじめエクセルにまとめておいて、コーディングを行うときに自動生成、みたいなスクリプトを作っておけばいいかもしれませんね。そうすれば、テスト書く人は、エクセルをいじればいいだけだから、作業効率も上がりそう。


あと、リンク先にも書いてあったけど、単体テストGUIが含まれていると、単体テストの効率が一気に下がります。GUIの操作が必要になってしまうとテスターの人が入力しないといけなくなってしまうので。
そのため、GUIの部分とそうでないロジックの部分を綺麗にわける必要があります。そうすることでテストもやりやすくなるし、コードの見通しがよくなって保守性が高まります。
よって、GUIが定義されるフォームにはテストが必要になるようなロジックを組み込まないようにするのが基本です。


単体テスト、大事。テストファーストっていうしね。そのうち、Objective-CでもOCUnitというものがあるみたいなので試してみたいと思います。