vbUnitを活用する

vbUnitの目的

これからご紹介するvbUnitの背景にはXPという開発手法が存在します。 これからの話の前提として、まず次のページをざっと見ておくとよいでしょう。

eXtreme Programming (by オブジェクト倶楽部)

Software Information (by 青木淳夫さん)

XPの12のプラクティスの中でも、テスティングについては、下記の目的を達成することができ、かつすぐに取り組みを始めることができると思いますので、すぐにでも始めていただきたいと思います。

vbUnitの他にもjava用のJUnit等が有名ですが、これらはテスティング「フレームワーク」であり、 これを利用することにより、テストプログラムが「簡単に」作れることになります。
※「簡単に」というのは多分適切でなくて、「統一的に」とか「余計なことに煩わされずに」というのが正解でしょうか?

入手とセットアップ

http://www.vbunit.org/index.html
まずは、ここからスタートです。しかし、英語の苦手な方もいらっしゃると思いますので、そのような場合は青木さんのページをご覧ください(VBUnit2のドキュメントの翻訳があり、またvbUnit3についても各情報があります)。 また、「VBUnit(NUnit)利用ガイド」 (by 小井土さん)も便利です。

セットアップ手順に関しても、青木さんのページに書いてあります。setup.batでdllをレジストリに登録するだけですので、特に問題ないと思います。
セットアップまでの手順についてはこれら以上に書く必要はないでしょう。
ちなみに、この資料もあくまでも取っ掛かりです。実際にやってみるのが一番!

vbUnit3について

9月末に待望のvbUnit3の正式版がリリースされました。以下の記述は基本的に3についてです。
しかしながら、vbUnit3の大きな特徴である、IDEとの統合部分(vbUnitAddIn.dll等TestRunner 関連)については プロフェッショナル版としてフリーではなくなってしまい、30日評価版として配布されています。 別途ベーシック版ではTestRunner 部分はvbUnit2が配布されています。
プロフェッショナル版も応援したいですが、ベーシック版ページも作成したいと思います。

まずは簡単に

まず、何を作るかですが、こちらからCOMコンポーネントのサンプルをもらってきました。簡単な計算結果を返すコンポーネントです。 これに対するテストを作ってみます。

  1. KeisanCOM.vbpを開く
  2. [ファイル]>[プロジェクトの追加]>[vbUnitTestDLL]
  3. vbUnitTestDLLを右クリックして[スタートアップとして設定]
  4. [アドイン]>[Run vbUnit TestSuite ...]でテストが正常に動作することを確認
  5. 次のようなテストを追加
  6. Public Sub TestTashizan()
    
    	Dim l_ShisokuKeisan As Object
    
    	Set l_ShisokuKeisan = CreateObject("KeisanCOM.ShisokuKeisan")
    
    	m_assert.LongsEqual 5, l_ShisokuKeisan.Tashizan(1, 2), "FailOK Tashizan no test"
    	m_assert.LongsEqual 3, l_ShisokuKeisan.Tashizan(1, 2), "Tashizan no test"
    
    	Set l_ShisokuKeisan = Nothing
    
    End Sub
    

  7. もう一度[アドイン]>[Run vbUnit TestSuite ...]

うまくいきましたでしょうか?
動作テストの「hello」と、わざと失敗させたexpected:5が表示されたと思います。 それらをクリックすればソースのその行に飛んでいきます。素晴らしい!

名前付けとファイル構成

名前付け規則

上記のようなデフォルトのままでは、そのうち分かりにくくなってしまうので、 名前付け規則を作ってその通りに作成することにします。 私がVBUnit2のときに考えていたのは次のようなものですが、 今後vbUnit3の特徴を生かして変更するかもしれません。
作成するDLLをprj_package.dllとします(「_」を好まない方がいらっしゃると思いますが、 windowsでファイル名・フォルダ名の大文字・小文字はどうも信用できないので、全て小文字でこのようにしています)。

prj\package\
	prj_package.vbp
	class1.cls(func1,func2)
	class2.cls
prj\package\test\
	test_prj_package.vbp(vbUnit3はスイートのテンプレートを用意してくれたのでそのままvbUnitTestDLL.vbpでよいかも)
	vbUnitTestSuite.cls(テンプレートのものをそのまま使います)
	test_class1.cls(Test_func1,Test_func2)
	test_class2.cls
	(クラス名はデフォルトのままでなく、クラスごとのほうが分かりやすいように思います。メソッド名は作成プログラムのメソッドが大文字で始まるならば「_」は不要だと思いますが、私は小文字で始めたいのでこのようにしています)

VBUnit2のときは、testの中にrun_test.vbpも入れていたのですが、vbUnit3ではこれが不要になりました。

ここで、二つのプロジェクトをプロジェクトグループにしておくと便利なはずなのですが、時々(おそらくロングファイルネームを使用していると)プロジェクトグループが破損します(そんなことないですか?)。 対処に慣れていないと、それまでの作業を無駄にするという結果を引き起こしかねません。
ここだけは面倒ですが、プロジェクトグループファイルはあてにせず、毎回プロジェクトの追加を行って作業をしたほうがよいと思います。

実際の作業例

それでは、ひとつサンプルを作ってみます。

[作成内容] ホテルの宿泊予約の料金計算コンポーネントを作成します。 料金は宿泊する日にちと部屋のタイプで決まります。一度の予約で複数部屋(2部屋)予約することが可能です。(画面

基本的には、テストファーストで実装していきます。すなわち、まずテストを考えてユニットテストを作成し、 それが通るように目的のクラスを実装していきます。 もっとも、最初だけは、ある程度の大枠がないと進めようがないですから、この程度のところまで作成します。 この時点でVSSにも登録します。 (プロジェクトエクスプローラコード

ここから、テストを作っていくことにします。 「まずは簡単に」でやったように、プロジェクトの追加でvbUnitTestDllを追加します。 ひとつのプロジェクトにひとつのテストプロジェクト、という形にするので、プロジェクト名とテストスイートの名前は このままでよいでしょう。(多数のdllを作るとすると、名前を付けたほうがよいか??)
フィクスチャはクラスごとに作成するので、クラス名をつけます。まず、すでに登録されているクラスの名前を「test_order」にします。 さらに、[プロジェクト]>[クラスモジュールの追加]でvbunitTestFixtureを選択し、もうひとつのクラスを追加します。 こちらの名前を上と同じように「test_detail」とします。 フィクスチャを作ったら、スイートに登録します。スイートのコードを開いて下の2行を記述します。

	'TODO: Add your Fixtures here
	suite.AddFixture New test_order
	suite.AddFixture New test_detail
ここで、テストプロジェクトを保存しておきます。 現在作成中の「order」フォルダの中に「test」フォルダを作成し、 その中に各テストプログラムを保存します。

それでは、テストを書きます。まず、本当にテストが動作しているかを確認しているために、失敗になるようなテストを書きます(テストコード)。 そして実行すると、こんな画面が出るでしょう。
(画面)

今回のバージョンでカラーになりました!また、フォントの指定ができるようになりましたので、 日本語を表示できるように 指定してください(右クリック>Options)。・・・と、最初はそうだったのですが、 バージョン3.04.07からは改めてフォントを設定しなくてもきちんと日本語を表示してくれます。 2行目はhelloと出るはずですが、hしか出ていないのはご愛嬌ですね。 (現在お願い中→正式版でも直らなかったようです。残念。→次期バージョンで修正される見込みです!→バージョン3.06.00で修正されました。粘り強く修正してくれたBodoさんに感謝!)

また、Test_retChargeの結果が1行しか出ていませんが、これは設定によって変えられます。 最初のテストのIFixture_Setupを次のようにします。

Private Sub IFixture_Setup(assert As IAssert)
    Set m_assert = assert
    m_assert.SetSeverity vbUnit_Assertion, vbUnit_AllTests
End Sub
VBUnit2ではこの状態がデフォルトだったのですが、今回、あえてこのように変えたそうです。 私は、全て実行してくれたほうが よいと思うので、上記記述を書くようにしようと思います。 ただ、この辺の動きは非常によくなっており、例えば、VBUnit2では テスト中の実行時エラーのトラップは自分で行わなければならなかったのですが、 今回は何もしなくても処理してくれます。 例えば、わざと存在しないメソッドを使ってみたりすると、 次のような画面になります。
(画面)

このような状態で、テストが正常に動くことを確認したら、後はテストを書いては実装して、の繰り返しです。

[複数人でひとつのプロジェクトを扱う場合]

夜間等自動実行

プロジェクトが進んでくると、テストの自動実行がほしくなります。ふと気づいたら動かなくなっていた プログラムってないですか?「この前まで動いていたのに・・・」
そのようなことをなくすために、毎日テストをするのです。そして、それを自動でやらせるために、 vbUnit3のバッチモードを利用します。
何はともあれ、まずはバッチモードでテストを実行してみましょう。
まず、目的クラス・テスト共、コンパイルしdllにしておきます。そして、RunVBUnitでテストを実行します。 下のようなコマンドを含むバッチファイルをテストフォルダに置いて実行したら下のような画面が表示されました。

@echo off
echo テストを開始します:
D:\usr\local\vbUnit3\bin\RunVBUnit vbUnitTestDll.vbUnitTestSuite
echo.
echo.
pause

これを一箇所にまとめておく等すれば、毎日自動で実行することも可能でしょう。結果をhtml等に吐き出して 開発者全員が見られるところに自動で公開されればベターですね!(近い将来作ります)
なお、青木さんのページでvssからのチェックアウト・コンパイルも含めたバッチファイルが 公開されています(VBUnit2)。

テストデータ

(テストとデータの分離)
結城さんのページにこのようなアイデアがありました。
このような考え方は素晴らしいと思うので、是非取り入れたいと思います。
すなわち、xUnitの各ツールは、詳細にテストを書いておくことこそが生命線であり、何か怪しいところがあったら そのテストをすぐに記述し、実行するという行為が必要になるはずです。 そのときに、テストを書くことが面倒になってはいけないですし、あるいは今回のVBUnit2からvbUnit3のメソッド名の 変更のような場合にもスムーズに移行できなければいけないわけです。
そこで、xmlの活用ということが考えられます。すなわち、テスト内容はデータとしてxmlファイルに置いておき、 テストプログラムはデータを読み込んで自動実行するわけです。これにより、テストプログラムを知らなくてもテストを 追加することができますし、テスト追加後にテストプラグラムをコンパイルする必要もありません。 場合によってはテスト仕様書の自動生成というような副産物も生み出すことができるかもしれません。

GUIアプリケーションの場合

(未完成)http://www.amazon.co.jp/exec/obidos/ASIN/4894712237/qid%3D998839155/249-9682892-8813941
テキストボックスをデータ連結にするが、そのデータはテーブルそのものではなくコンポーネントにする?