テスト・ケースの作成 : %UnitTest.TestCase クラス
これは、%UnitTest フレームワークを使用してユニット・テストを設定する一般的なワークフローです。
-
%UnitTest.TestCaseOpens in a new tab クラスを拡張し、テスト対象のメソッドごとに 1 つのテスト・メソッドを追加します。テスト・メソッド名は、Test という単語で始まる必要があります。"%UnitTest.TestCase クラスの拡張" を参照してください。
-
1 つのテスト・メソッドに複数のテストを含めることができます。通常、テスト・メソッドには、テスト対象のメソッドの各側面につき 1 つのテストが含まれます。各テスト・メソッド内で、$$$AssertX マクロを使用して 1 つ以上のテストを作成します。通常、マクロはテスト対象のメソッドを呼び出し、その出力を期待値と比較します。期待値がマクロの出力と一致する場合、テストは成功と見なされます。"%UnitTest.TestCase クラスのマクロ" を参照してください。
-
準備メソッドとクリーンアップ・メソッドにコードを追加して、必要なタスクを実行します。例えば、テストでリストから要素を削除する場合、まずそのリストが存在し、そこに削除する要素が含まれている必要があります。"%UnitTest.TestCase クラスの準備メソッドとクリーンアップ・メソッド" を参照してください。
Note:準備メソッドとクリーンアップ・メソッドはしばしば、セットアップ・メソッドおよびティアダウン・メソッドとも呼ばれます。
%UnitTest.TestCase クラスの拡張
%UnitTest.TestCaseOpens in a new tab を拡張するクラスを作成し、ユニット・テストを実行するテスト・メソッドを含めます。このプロセスは、特定のテスト・ニーズに対応できるよう柔軟な設計になっています。
ほとんどの場合、テスト・メソッドを追加し、プロパティも追加します。テスト・メソッドは、‘Test’ で始まる名前のメソッドを探して実行する %UnitTest.ManagerOpens in a new tab クラスの RunTests() メソッドによって実行されます。クラスに他のヘルパー・メソッドを追加することはできますが、RunTests() を呼び出したときにメソッドがユニット・テストとして実行されるのは、メソッド名が ‘Test’ で始まる場合のみです。
テスト・メソッドはアルファベット順に実行されます。例えば TestAssess() は TestCreate() より前に実行されます。
テスト・メソッド内では、1 つ以上のテストを作成します。各テストに $$$AssertX マクロを使用します。$$$AssertX マクロの詳細は、"%UnitTest.TestCase クラスのマクロ" を参照してください。
テストするクラス・メソッドごとにテスト・メソッドを作成することもできます。例えば、MyPackage.MyClassToBeTested クラスに複数のテストを呼び出す Add() メソッドが含まれる場合、必要なテストを実行するコードを含む MyTests.TestAdd() テスト・メソッドを作成できます。
オブジェクト・インスタンスをテストすることもできます。この場合、オブジェクトのプロパティと機能が正しいことを確認するテストを含めることができる、MyTests.TestMyObject() のようなメソッドを作成します。
テスト・メソッドを作成するほかに、拡張クラスではプロパティを作成することもできます。これにより、テスト・メソッドは情報を共有できます。プロパティを追加する際は、以下の点を考慮してください。
-
クラス自体でカスタム・プロパティを宣言します。
-
..<property> 構文を使用し、準備メソッド OnBeforeOneTest() および OnBeforeAllTests() にコードを追加してプロパティを設定します。
-
..<property> 構文を使用し、テスト・メソッドやクリーンアップ・メソッド OnAfterOneTest() および OnAfterAllTests() にコードを追加してプロパティにアクセスします。
Note:例えば、カスタム・プロパティが PropertyValue と呼ばれる場合、..PropertyValue を使用して設定またはアクセスできます。
例 : 拡張 %UnitTest.TestCase クラス
Class MyPackage.MyClassToBeTested { Method Add (Addend1 as %Integer, Addend2 as %Integer) As %Integer { Set Sum = Addend1 + Addend2 Return Sum } } Class MyPackage.MyTests Extends %UnitTest.TestCase { Method TestAdd() { do $$$AssertEquals(##class(MyPackage.MyClassToBeTested).Add(2,3),5, "Test 2+3=5") do $$$AssertNotEquals(##class(MyPackage.MyClassToBeTested).Add(3,4),5, "Test 3+4 '= 5") } }
%UnitTest.TestCase クラスのマクロ
各テスト・メソッド内で、以下のいずれかの $$$AssertX マクロを使用して、クラス・メソッドのテスト可能な側面をテストします。例えば、テスト・メソッドが Add() メソッドをテストするように設計されている場合、これには、$$$AssertEquals を使用して 2+3 が 5 になることを確認するテストと、$$$AssertNotEquals を使用して 3+4 が 5 にならないことを確認するテストを含めることができます。
必要なテスト結果に最も一致するマクロを選択します。この原則を考慮する方法として、アサーションが成功するという観点からテストを作成することもできます。2 つの値が等しくなることを期待する場合は $$$AssertEquals を使用し、等しくならないことを期待する場合は $$$AssertNotEquals を使用します。
指定した $$$AssertX マクロが False を返す場合、テストは不合格で、そうでない場合、テストは合格です。
$$$AssertX マクロは、次の引数を取ることができます。
-
arg1 — 通常、テスト対象のメソッドの出力、またはその出力から計算された値です。
-
arg2 — 存在する場合、マクロが arg1 と比較する値です。
-
test_description — 表示されたテスト結果のリストにある文字列で、マクロが何をテストしたかを示します。これは、テストの結果には影響しません。この引数には、連結、変数、メソッドを含めることができます。例えば、値は以下のようになります。
“Failed to create” _ maxObjects _ "objects: " _ $system.Status.GetErrorText(status)
arg1 と arg2 が等しい場合、True を返します。
do $$$AssertEquals (##class(MyPackage.MyClassToBeTested).Add(2,3), 5, “Test Add(2,3) = 5”)
arg1 と arg2 が等しくない場合、True を返します。
do $$$AssertNotEquals (##class(MyPackage.MyClassToBeTested).Add(3,4), 5, "Test Add(3,4) '= 5")
返されたステータス・コードが 1 の場合、True を返します。
do $$$AsserStatusOK(##class(MyPackage.MyClassToBeTested).SaveContact(valid_contact_ID), "Test that valid contact is saved")
返されたステータス・コードが 1 でない場合、True を返します。
do $$$AssertStatusNotOK(##class(MyPackage.MyClassToBeTested).SaveContact(invalid_contact_ID), "Test that invalid contact is not saved")
式が True の場合、True を返します。
do $$$AssertStatusTrue(##class(MyPackage.MyClassToBeTested).IsContactValid(valid_contact_ID), "Test that valid contact is valid")
式が True でない場合、True を返します。
do $$$AssertStatusNotTrue(##class(MyPackage.MyClassToBeTested).IsContactValid(invalid_contact_ID), "Test that invalid contact is not valid")
2 つのファイルが同じである場合、True を返します。
do $$$AssertFilesSame(##class(MyPackage.MyClassToBeTested).FetchFile(URL), control_file, "Test that fetched file is identical to control file")
SQL クエリ結果を含む 2 つのファイルに、順序付けられていない同じ結果が含まれる場合、True を返します。
do $$$AssertFilesSQLUnorderedSame(output.log,reference.log,"Comparing output.log to reference.log")
無条件で成功をログに記録します。このアサーションは、$$$AssertTrue に 1 を渡す規則を置き換えることを目的としています。
無条件で失敗をログに記録します。このアサーションは、$$$AssertTrue に 0 を渡す規則を置き換えることを目的としています。
test_description で説明されている理由でテストがスキップされたというメッセージをログに記録します。これは、例えばテストの前提条件が満たされていない場合に使用されます。
OnBeforeAllTests() は、このマクロをサポートしていません。OnBeforeAllTests() で $$$AssertSkipped を呼び出すと、誤検出が発生する可能性があります。
特定のテストとは無関係に、message の値をログ・エントリとして書き込みます。これは、例えばログにコンテキストや編成を提供する場合に非常に便利です。
do $$$LogMessage("-- ALL TEST OBJECTS CREATED -- ")
%UnitTest.TestCase クラスの準備メソッドとクリーンアップ・メソッド
テスト・クラスの各テスト・メソッドの直前に実行します。
テスト・クラスのすべてのテスト・メソッドの前に 1 回だけ実行します。
テスト・クラスの各テスト・メソッドの直後に実行します。
テスト・クラスのすべてのテスト・メソッドが実行された後に 1 回だけ実行します。
例 : 準備メソッド
このメソッドのコードは、テスト・スイートの実行前に 1 回実行されます。テスト中に使用する単一コンタクトを作成します。準備タスクを複数回実行するには (スイートの各テストの前に 1 回ずつ)、代わりに OnBeforeOneTest() にコードを追加します。
Method OnBeforeAllTests() { Do ##class(MyPackage.Contact).Populate(1) Return $$$OK }
例 : クリーンアップ・メソッド
このメソッドのコードは、テスト・スイート全体の実行後に 1 回実行されます。テストの完了後、エクステントのすべてのコンタクトを削除します。クリーンアップ・タスクを複数回実行するには (スイートの各テストの後に 1 回ずつ)、代わりに OnAfterOneTest() にコードを追加します。
Method OnAfterAllTests() { Do ##class(MyPackage.Contact).%KillExtent() Return $$$OK }