【IRIS/Cache】ユニットテスト(確認編)

本記事は、ユニットテストシリーズ最後の「テスト結果の確認」について解説します。

※この記事は下記の方向けになります。
  • 長期間運用が想定されるシステムを構築する方
  • 不具合が多くて悩んでいる方
  • コードの品質向上を目的とした、ユニットテストの導入検討を行っている方

ユニットテストを確認するには、ユニットテストの作成/実行を行う必要があります。

もし、前回を確認していない場合は、下記から参照してください。

はじめに

本記事は、ユニットテストの確認編となります。

ユニットテストの確認は、管理ポータルから行うことが可能です。
[システムエクスプローラー] > [ツール] > [ユニットテスト・ポータル]

この画面では、今まで行ってきたユニットテストの一覧が表示され、前回の記事で行ったユニットテストもここから確認する事ができます。

とは言え、前回ユニットテスト実行時に「表示されたURLから確認する」と記載したので、下記URLを直接ブラウザに張り付けて確認してみましょう。

<http://[IPアドレス]:[PORT番号]>/csp/sys/%25UnitTest.Portal.Indices.cls?Index=59&$NAMESPACE=SAMPLE

【ユニットテストの結果一覧が開かない場合】

一覧がエラーを表示し、正常に開かない場合」があります。

これは、設定が足りていない状態なので、ターミナルを起動し、下記コマンドを実行します。

zn "%SYS"
s ^SYS("Security", "CSP", "AllowPrefix", [ウェブアプリケーションパス], "%UnitTest.")=1

■[ウェブアプリケーションパス]の設定値

ネームスペース「TUNAKAN」のデフォルト・ウェブサイトの名称が「/csp/tunakan」であれば、下記になります。

^SYS(“Security”,”CSP”,”AllowPrefix”,”/csp/tunakan/“,”%UnitTest.”)=1

※名称の最後に「/」が付与されています。

■グローバル確認

再度管理画面から一覧を表示してみます。

ユニットテストの結果一覧が正常に表示されました!

ユニットテストの確認

では、先ほどのURLをブラウザで実行してみましょう。

今回実施した3つのスイートが全て表示されています。
また、この時点で成功/失敗したスイートが確認できます。

この画面は、ユニットテストの詳細を確認する為に、テストスート>テストケース>テストメソッドと各項目をドリルダウンしていく必要があります。

では、「失敗」したテストスイート「sampleFile」をクリックします。

テストスイート

テストスイートからみると「失敗」した「sampleFile」ですが、配下には2つのテストケースがあり、片方が「成功」し、もう片方が「失敗」したのが確認できます。

結果は想定通りですね。

次は、「成功」したテストケース「developer.export.UnitTestFile」をクリックします。

テストケース

テストケース「developer.export.UnitTestFile」配下のテストメソッドが表示されます。

このテスト・クラスには、1つのテストメソッドを記述したので、表示されている項目も1つになります。

次はこのドリルダウン最後の項目である、テストメソッド「TestFileDelete」をクリックします。

テストメソッド

テスト成功ケース

今回の検証結果が表示されます。

検証が「成功」しているのが確認できます。

では、「失敗」したテストの状況を確認してみましょう。

テスト失敗ケース

末端までドリルダウンしたので、最初のページに戻る必要があります。
画面ヘッダ部分の「LogIndex:59」の「59」をクリックしましょう。

最初の画面に戻ったら、下記順にクリックします。
[sampleTest] > [developer.export.UnitTest] > [TestAdditionError]

エラーを起こしたテスト結果が表示されています。

赤文字で「failed」の単語を見ると、少し不安になりますね・・・。

兎にも角にも、このテストメソッドがどの様な構成だったか確認してみましょう!
 ※ マクロとDescriptionを確認してみて下さい。

グリッドの列「Counter=1」は、関数 25行目のコメント「$$$LogMessage」を指しています、「Counter=3」は32行目のコメント「$$$AssertFailure」になります。

「Counter=2」は、チェックマクロ「$$$AssertEquals」の結果になります。

「6+1」の結果と「7」を比較検証しているため、想定通り「failed」となりました。

「Counter=4」は、このテストメソッドの実行時間です。

所感

うん。
画面からテスト結果を確認するとして、とても確認し難いと感じます。

各項目をドリルダウンしないと詳細が見れないのが不満です。

やっぱり、検証結果は全体を通して確認できる方がありがたいですよね。

公式が確認し難いのであれば、ロジックを組んでオリジナルで結果を表示してみましょう。

ユニットテストの自力確認

自力で確認するには、クラスの構成を知る必要があります。

テストクラスの構成は下記となっています。
なんとなくイメージしやすいですよね。

 %UnitTest.Result.TestInstance
  └ %UnitTest.Result.TestSuite
    └ %UnitTest.Result.TestCase
      └ %UnitTest.Result.TestMethod
        └ %UnitTest.Result.TestAssert

各クラスは親子関係のリレーション関係になります。

では、これらのクラスを利用して、テスト結果を表示してみましょう!

簡単なサンプル紹介

ロジックで確認する

Objectscriptを使っていると、ついついロジックを組みたくなりますよね。

ユニットテストの結果を、ターミナルに出力するサンプルを作成しました。

ClassMethod getResult(id As %Integer)
{
	#dim e as %Exception.AbstractException
	#dim inst as %UnitTest.Result.TestInstance
	#dim suite as %UnitTest.Result.TestSuite
	#dim case as %UnitTest.Result.TestCase
	#dim meth as %UnitTest.Result.TestMethod
	#dim ass as %UnitTest.Result.TestAssert
#;	#define E ","
	#define E $c(9)
	
	try{
		s inst = ##class(%UnitTest.Result.TestInstance).%OpenId(id)
				
		//-----------------------------------------------------------------------------
		// suite
		s (suiteKey, instText) = ""
		f {	s suite = inst.TestSuites.GetNext(.suiteKey) q:('$IsObject(suite))
		
			//-----------------------------------------------------------------------------
			// case
			s caseKey = ""
			f { s case = suite.TestCases.GetNext(.caseKey) q:('$IsObject(case))
			
				//-----------------------------------------------------------------------------
				// method
				s methKey = ""
				f { s meth = case.TestMethods.GetNext(.methKey) q:('$IsObject(meth))
					
					//-----------------------------------------------------------------------------
					// asserts
					s assKey = ""
					f { s ass = meth.TestAsserts.GetNext(.assKey) q:('$IsObject(ass))
						
						w !,inst.MachineName,$$$E,
						    inst.ConfigurationName,$$$E,
						    inst.DateTime,$$$E,
						    inst.Namespace,$$$E,
						    inst.Version,$$$E,
						    
						    suite.Name,$$$E,
						    suite.Status,$$$E,
						    suite.Duration,$$$E,
						    
						    case.Name,$$$E,
						    case.Status,$$$E,
						    case.Duration,$$$E,
						    case.ErrorDescription,$$$E,
						    
						    meth.Name,$$$E,
						    meth.Status,$$$E,
						    meth.Duration,$$$E,
						    meth.ErrorDescription,$$$E,
						    
						    ass.Counter,$$$E,
						    ass.Action,$$$E,
						    ass.Status,$$$E,
						    ass.Description
					}
				}
			}
		}
	}catch e{
		w e.DisplayString()
	}
}

引数にレコードIDを渡します。

出力結果をファイルに出力する場合は、下記記事を参考にして下さい。

SQLで確認する

ユニットテストは、データクラスで構成されているのでSQLが利用可能です。
昨今のSQLツールは、非常に便利になっているのでそれらを利用しても良いでしょう。

今回は手軽に管理ポータルを利用してみます。

下記クエリを基本に適宜クエリを調整してください。

select
 i.ID,
 i.MachineName,
 i.ConfigurationName,
 i.DateTIme,
 i.Namespace,
 i.Version,

 s.Name,
 s.Status,
 s.Duration,

 c.Name,
 c.Status,
 c.Duration,
 c.ErrorDescription,

 m.Name,
 m.Status,
 m.Duration,
 m.ErrorDescription,

 a.Counter,
 a.Action,
 a.Status,
 a.Description

from %UnitTest_Result.TestInstance as i
 left join %UnitTest_Result.TestSuite as s
 on i.id=s.TestInstance

 left join %UnitTest_Result.TestCase as c
 on s.ID=c.TestSuite

 left join %UnitTest_Result.TestMethod as m
 on c.ID=m.TestCase

 left join %UnitTest_Result.TestAssert as a
 on m.ID=a.TestMethod

where
 i.id=[LogIndex] // TestInstanceのレコードIDを指定します

実行するとこんな感じで表示されます。

色分けこそされていませんが、全テスト結果を一覧できるのは便利ですね。

CSV等に出力して加工するのもありだと思います。

おわりに

いかがだったでしょうか。

Objectscriptに標準実装されている確認画面は、テスト結果を確認するには煩雑で見難いところがあります。

テストの視認性や記述性をどう高めるかは、開発効率を左右する大事な課題だと感じます。
本記事が、何らかの一助になれば幸いです。

テストコードは往々にして「一度書いて終わり」になりがちです。
実装の変更に合わせて読み返し、修正し、再実行しながらソフトウェアの品質を担保し続ける必要があります。

ユニットテストは、品質を守る最後の砦であると同時に、開発者とコードの信頼関係を築く大切なツールです。

「とりあえず動くテスト」から「読みやすく・育てやすいテスト」へと意識を少しずつ変えていくことで、長く健全なコードベースを保っていけるのではないでしょうか。