テスト
jasmine
unittest
ServiceNow
回帰

ServiceNowのテストフレームワークを使い倒す

概要

ServiceNowのAutomated Test FrameworkでRun Server Side Scriptのテストを作成すると、作成したテスト設定のTest Script欄にコメントで詳細なテスト方法が記述されている、その内容を読み解きながら実際に試してみる。

本題

Jasmineとの住み分け

// You can use this step to execute a variety of server-side javascript tests including
// jasmine tests and custom assertions

jasmineとServiceNowの独自のテストフレームワークの2種類を使用する事が出来る。
ServiceNowのテスト機能を最大限に活用するには、ServiceNow のテスト機能を使うのが良いだろう。

戻り値について

// Pass or fail a step: Override the step outcome to pass or fail. This is ignored 
//                      by jasmine tests
//
//  - Return true from the main function body to pass the step
//  - Return false from the main function body to fail the step

戻り値として、trueを返すとテスト成功(pass)
戻り値として、falseを返すとテスト失敗(fail)
と判断される。

なお、この戻り値によるテストはjasmineテストの場合は、無視される。

戻り値を試してみる

trueを返す

(function(outputs, steps, stepResult, assertEqual) {
    // add test script here
    return true;

})(outputs, steps, stepResult, assertEqual);

return true.png

falseを返す

(function(outputs, steps, stepResult, assertEqual) {
    // add test script here
    return false;

})(outputs, steps, stepResult, assertEqual);

return false.png

outputsを使ってテストステップ間でデータの受け渡しを行う

// outputs:       Pre-defined Step config Output variables to set on this step during 
//                execution that are available to later steps
//
// steps(SYS_ID): A function to retrieve Output variable data from a step that executed
//                earlier in the test. The desired step's sys_id is required

outputsオブジェクトに値を設定することにより、以降のテストステップに値を受け渡すことが可能。
以降のテストステップでは、steps関数により前のテストのoutputsオブジェクトを取得することが可能。

outputsを試してみる

1つ目のテストステップ

(function(outputs, steps, stepResult, assertEqual) {
    var salesRecord = new GlideRecord('x_211750_angular_a_sales');
    salesRecord.setValue('customername','test user');
    salesRecord.setValue('unitprice', 200);
    salesRecord.setValue('quantity',4);

    outputs.record_id = salesRecord.insert(); 

})(outputs, steps, stepResult, assertEqual);

なお、2つ目のテストステップのこのテストステップのsys_idが必要となるので、
Test Stepのメニューの「Copy sys_id」でsys_idをクリップボードにコピーしておく。

copy_sys_id.png

2つ目のテストステップ

(function(outputs, steps, stepResult, assertEqual) {

    var previoudObject = steps('57ad9350dbe11b0004f171efbf96190d');
    gs.info('previoudObject.record_id = ' + previoudObject.record_id);
    var salesRecord = new GlideRecord('x_211750_angular_a_sales');

    salesRecord.get(previoudObject.record_id);

    var assertion = {
        name: "レコードがありました", 
        shouldbe: 'test user', 
        value: salesRecord.customername};

    assertEqual(assertion);

    return true;

})(outputs, steps, stepResult, assertEqual);

steps関数について説明する。

var previoudObject = steps('57ad9350dbe11b0004f171efbf96190d');

steps関数により前のステップのoutputsオブジェクトを取得が可能だ。
steps関数の引数は、outputsオブジェクトを取得したいテストステップのsys idだ。
テストステップのsys_idは1つめのテストステップを作成時にクリックボードにコピーしたものだ。
テストの中で既に実行済みの任意のテストステップのoutputsを取得できる。

実行結果は次の通り

outputtestresult.png

stepResult.setOutputMessageでテスト結果を明示的に出力する

// stepResult.setOutputMessage: Log a message to step results after step executes.
//                              Can only be called once or will overwrite previous 
//                              message
//

Test Resultにテストの検証結果をテストステップごとに出力が可能。
なお、1つのテストステップでメッセージは1回のみ設定可能で、後勝ちになる。

stepResult.setOutputMessageを使ってみる

(function(outputs, steps, stepResult, assertEqual) {
    stepResult.setOutputMessage('レコードの検証に成功しました。');

    return true;
})(outputs, steps, stepResult, assertEqual);

実行結果は次の通り

messageresult.png

describeやitについて

// Note: describe is only supported in Global scope.
// Use 'describe' to create a suite of test scripts and 'it' to define test expectations

describeやitというのはjasmineテストフレームワークで使用するもので、
itでテストケースの定義、describeでテストスイートの定義を行うが、
ServiceNowを使用する場合は、ServiceNowのTest Suite機能を利用するので、jasmineのdescribeやitは通常は利用しないだろう。

使用する場合はGlobalスコープでのみ使用可能。

// make sure to uncomment jasmine.getEnv().execute(); outside the function body

また、jasmineのテストフレームワークを利用するには、下記の行のコメントアウトを解除して有効にしておく必要がある。

jasmine.getEnv().execute();

assertEqualで検証

// assertEqual: A function used to compare that assertion.shouldbe == assertion.value;
//              in case of failure it throws an Error and logs that the assertion by
//              name has failed

こちらは既に試しているが、値を検証するのに使用する。
次のようなオブジェクトを引数に指定して実行する。

   var assertion = {
        name: "レコードがありました", 
        shouldbe: 'test user', 
        value: salesRecord.customername};

   assertEqual(assertion);

outputsの2つ目のステップのコードで利用しているので、そちらで確認して欲しい。
なお、オブジェクトのプロパティは次の通り

名称 説明
name 検証の説明を書く
shouldbe 期待する値
value 実際の値