ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

MUMPS好き好き。コミュの%UnitTest

  • mixiチェック
  • このエントリーをはてなブックマークに追加
%UnitTest : Cache'での xUnit(単体テストフレームワーク)

面白いので、長くなりますが概要を書きます。

Cache' Version 5.0.? から、ライブラリー(%CACHELIB)Classに、%UnitTest Packageが入ってましたが、InterSystemsからのドキュメントはありませんでした。

Ramon Jimenez氏が、Classソースを解析して、紹介文を書いています。
Unit Testing in Cache
http://personal.vsnl.com/sukesh_hoogan/csnips.html#Nbr02

最近の Cache V5.1 でInterSystemsから%UnitTestのドキュメントが出ました。
http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=TUNT_preface

Cache' e-Learning
http://elearning.intersystems.com/
に、%UnitTestに関する Recorded Webcasts があります

5/26/05 Percent UnitTest I Test as You Build  052605 Themis Carr 28m
6/9/05 Percent UnitTest II Test as you Build  060905 Themis Carr 38m

Carrさんによると、このツールは、InterSystemsのクオリティ部門でCache'自身をテストをするために作成された。特にWindows/Unix/Linux/VMS等の様々なプラットフォームでの(同じ結果になるか)自動再帰テスト(毎夜実行、あくる日に確認)に有効に使われているようです。

コメント(3)

%UnitTestの概要

1) テスト処理プログラム

テスト処理は、Classの Method に書く。
そのClassは、%UnitTest.TestCase を Extends(継承)すること。
テスト処理Methodの name は Test で始めること。

その処理で以下のAssertマクロ使って動作検査をします。

$$$AssertEquals
$$$AssertNotEquals
$$$AssertTrue
$$$AssertNotTrue
$$$AssertStatusOK
$$$AssertStatusNotOK
$$$AssertStatusEquals
$$$AssertFilesSame
$$$LogMessage
(詳細は、Includeルーチン %outUnitTest.INC)

http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=TUNT_PrimaryClasses

InterSystemsドキュメント
http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=TUNT_Part2Intro
PartIIの例

Class UnitTest.test Extends %UnitTest.TestCase
{
Method TestAdd()
{
do $$$AssertEquals(##class(UnitTest.TestMe).Add(2,2),4, "TestMe Add(2,2)=4")
do $$$AssertNotEquals(##class(UnitTest.TestMe).Add(2,2),5,"TestMe Add(2,2)'=5")
}
}

ここで、テストする処理は以下のAdd関数です。

Class UnitTest.TestMe
{
ClassMethod Add(Arg1 As %Integer, Arg2 As %Integer) As %Integer
{
quit Arg1+Arg2
}
}


2) テストディレクトリー

Unit-Testは、再帰テストを前提とするために、実行環境の前提条件は何も仮定しない。テスト時に自分で初期化するようにプログラムする必要がある (%UnitTest.TestCaseから継承した空のOnBeforeOneTest,OnBeforeAllTests,OnBeforeAllTests,OnAfterOneTest methodをオーバーロードする)。また、Unit-Testプログラムやテスト対象プログラムも、実行環境(この場合Cache')の外部ディレクトリー(test root directory)に置きます。

http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=TUNT_ExampleTestClass

で "Now export Test to your unit test directory"
とExportする必要があるのは、そのためです。

テストルートディレクトリーは、グローバル ^UnitTestRoot にセットします。

例 USER>set ^UnitTestRoot="c:\unittests\"

3) テストサブディレクトリー

Unit-Testの管理便宜上、2)のルートディレクトリーの下にサブディレクトリーを作り、そこに、1)のクラスをExportします。

例 C:\unittests\TestMe

ファイル test.xml

<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="20" zv="Cache for Windows (Intel/P4) 5.1 (Build 826suU)" ts="2006-03-15 21:42:38">
<Class name="UnitTest.test">
<Super>%UnitTest.TestCase</Super>
<TimeCreated>60338,1443.339477</TimeCreated>

<Method name="TestAdd">
<Implementation><![CDATA[
do $$$AssertEquals(##class(UnitTest.TestMe).Add(2,2),4, "TestMe Add(2,2)=4")
do $$$AssertNotEquals(##class(UnitTest.TestMe).Add(2,2),5,"TestMe Add(2,2)'=5")
]]></Implementation
</Method>
</Class>
</Export>

ファイル TestMe.xml

<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="20" zv="Cache for Windows (Intel/P4) 5.1 (Build 826suU)" ts="2006-03-15 16:14:25">
<Class name="UnitTest.TestMe">
<TimeCreated>60339,58107.752368</TimeCreated>

<Method name="Add">
<ClassMethod>1</ClassMethod>
<FormalSpec>Arg1:%Integer,Arg2:%Integer</FormalSpec>
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[ quit Arg1+Arg2
]]></Implementation>
</Method>
</Class>
</Export>

4) テスト実行

例 USER>d ##class(%UnitTest.Manager).RunTest("TestMe")

第一パラメータ、"TestMe" は、サブディレクトリー名。
%UnitTest.ManagerのRunTestは、サブディレクトリー内のClass Exportファイル *.cdl *.CDL *.xml *.XML を読み、取り込み実行する。--> $system.OBJ.LoadDir(dir)
取り込みClassの中に Test... のmethodを探し実行する。
テスト後、取り込んだClassはすべて削除されますの注意が必要です --> $system.OBJ.Delete(class,"-d")
テスト結果はグローバル ^UnitTestLog にsetされます。
実行端末の Use the following URL to view the result: でブラウザーで見ることが出来ます(ライブラリー%UnitTest.Reportを使用)。

テスト実行例
===============================================================================
Directory: C:\unittests\TestMe\
===============================================================================
TestMe begins ...
ディレクトリのロード開始 03/15/2006 21:42:48
ファイル C:\unittests\TestMe\TestMe.xml を xml としてロード中
インポートしたクラス: UnitTest.TestMe
ファイル C:\unittests\TestMe\test.xml を xml としてロード中
インポートしたクラス: UnitTest.test
クラスのコンパイル中 UnitTest.TestMe
クラスのコンパイル中 UnitTest.test
ルーチンのコンパイル中 UnitTest.TestMe.1
ルーチンのコンパイル中 UnitTest.test.1
ロードが正常に完了しました。

UnitTest.test begins ...
TestAdd() begins ...
AssertEquals:TestMe Add(2,2)=4 (passed)
AssertNotEquals:TestMe Add(2,2)'=5 (passed)
LogMessage:Duration of execution: .197477 sec.
TestAdd passed
UnitTest.test passed
TestMe passed

Use the following URL to view the result:
http://127.0.0.1:8972/csp/samples/%25UnitTest.Report.cls?NS=USER&INDEX=37

4) ロードなしのテスト実行

USER>do $system.OBJ.LoadDir("C:\unittests\TestMe")
であらかじめ取り込んでおき(あるいは、すでにある状態で)

USER>do ##class(%UnitTest.Manager).RunTest("TestMe:UnitTest.test","/noload")
でロードなしのテスト実行が可能です。

第1パラメータの TestMe:UnitTest.test の : の後ろは、Test...methodを含むテストClassを陽に指定します。第2パラメータのqualifiersで /noload を指定します。
qualifiersは、/が必要です。 "/nodebug/display=all/load/run/recursive" がそのデフォルト値ですが、ドキュメントには書かれていないようで、%UnitTest.Managerソースを見ないと(動きも)分りません。

5) その他
結果出力をファイルに書き出し(output.log)、参照ファイル(reference.log)とのファイル比較テストを行う %UnitTest.TestCacheScript や SQLコマンド列を実行し、ファイル比較テストを行うライブラリー Class%UnitTest.TestSqlScript があります。

6) 感想

再帰自動テストツールは、あれば!、相当安心!してプログラムの変更、メンテナンスが出来ます。構造化やオブジェクト指向と同じぐらい、あるいはそれ以上に効果があると思います。アジャイルであり"続ける"ためには必須かも知れません。
特に、M(UMPS)のように、簡単にプログラムが変られるため、コードレビューやテストを十分しないで安易にプログラムを変更してしまいがちな言語では、こうしたテストツールは必要です。%UnitTest はいい入り口の様に思います。
↑5.0.10.5300.0で試してみました。面白いですねー。

まだ、どんな場面で使うか具体的なイメージわきませんが、Mのコードも適当なクラスのメソッドにすれば同様にテスト出来そうです。

サイトのsukesh_hooganさんはインドの方みたいですねー(色遣いがインドっぽい、笑)。
Web屋のネタ帳
「オープンソースソフトの品質とその向上プロセスについて雑感」
http://neta.ywcafe.net/000583.html

PHP言語でバグをレポートされ、即座に修正版がリリースされた経験から、オープンソースソフトの品質とその管理サイクルについて書かれている。

印象に残ったのは、

<quote>
今回、メンテナーさんは筆者が投稿したバグの再現コードにちょっと手を加えただけでそのまま テストコードにしたようだ。自動単体テストと呼ばれる仕組みである。以後、すべての開発者はいつでもコマンド一発でこのテストを実施できる。二度と同じバグを発生させないための仕組みだ。多くの企業の開発現場で機能追加やバグ修正のためにコードに手を入れるたびにけだるそうな顔をしたプログラマーがMS-Excel上にずらりとならんだ単体テスト項目に沿ってひとつずつテストしなおしているのと比べると、なんと合理的なことか。
</quote>

こうした再帰自動(単体)テスト環境を作りたいものです。それがあれば、通常、修正が他のバグを生んだり潜在バグを顕在化さすため相当の勇気がいる、既存プログラムの整理(構造をきれいにする)や変更がかなり安心して出来る。

プログラムのエントロピー(複雑さ)はすぐ簡単に上がる。
逆にエントロピーを下げるのには相当なエネルギーがいる。ましたて、実稼動中のシステムでは。引用のような自動単体テストと呼ばれる仕組みは、是非作りたいものです。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

MUMPS好き好き。 更新情報

MUMPS好き好き。のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング