はじめに
前回(#03 Writing Scenarios)は、モックのサービスを作成して、実際にシナリオテストを実施してみました。
今回は、テストの幅を広げるために、Karateで、どのようにデータの定義をするのかを確認してみます。
テスト実施時に、リクエストの内容を指定したり、レスポンスの内容を確認したりするために、どのようにデータを定義するのか、ということになります。
データの指定方法
変数の指定
まずは、基本的な定義として、変数での指定をしてみます。
Scenario: Normal def
* def text = 'karate example'
* print text
* match text == 'karate example'
* def jatext = '日本語のテキスト'
* print jatext
* match jatext == '日本語のテキスト'
-
def
が、変数の定義です。 -
print
は、テスト実行時に、レポートに変数の内容を出力してくれます。 -
match
は、値の確認です。
実行したときのレポートの内容は、以下のような感じです。
問題なく、テストが通っていますね。
当然ながら、日本語も問題なく利用できます。
JSON形式のデータの指定
次は、JSONデータの指定方法について確認します。
REST-APIのテストに向けては、この辺りの使い勝手は重要ですね。
Scenario: JSON Format
# MultilineでのJSON指定
* def jsonData =
"""
[
{name: 'Bob', age: 2},
{name: 'Wild', age: 4},
{name: 'Nyan', age: 3}
]
"""
* match jsonData == [{name:'Bob', age:2}, {name:'Wild', age:4}, {name:'Nyan', age:3}]
基本的な指定の仕方として、マルチラインでの指定です。
"""
で囲むことによって、マルチラインでのデータの指定ができています。
# 値の変更
* set jsonData[0].age = 3
* match jsonData == [{name:'Bob', age:3}, {name:'Wild', age:4}, {name:'Nyan', age:3}]
先程指定した jsonData
のデータの一部を変更しています。
set
コマンドを利用することで、データを変更できます。
# table指定
* table jsonAsTable
| name | age |
| 'Bob' | 2 |
| 'Wild' | 4 |
| 'Nyan' | 3 |
* match jsonAsTable == [{name:'Bob', age:2}, {name:'Wild', age:4}, {name:'Nyan', age:3}]
今度は、テーブル形式でのJSONデータの指定です。table
コマンドを指定して定義しています。
生のJSONデータよりも、こちらの方が見やすいですね。
ただ、tableの場合、ネストされているようなJSONは定義できません。
# set指定(JSON Pathを意識した指定)
* set jsonAsSetMultipleSyntax
| path | 0 | 1 | 2 |
| name.first | 'John' | 'Jane' | 'David' |
| name.last | 'Smith' | 'Doe' | 'Brown' |
| age | 20 | 24 | |
* match jsonAsSetMultipleSyntax[0] == {name: { first:'John', last:'Smith' }, age:20}
* match jsonAsSetMultipleSyntax[1] == {name: { first:'Jane', last:'Doe' }, age:24}
* match jsonAsSetMultipleSyntax[2] == {name: { first:'David', last:'Brown' }}
ネストされたJSONデータを定義したい場合は、set
コマンドを利用することで可能です。
こちらも、テーブル形式に近い内容ですが、table
のときと比べて、行と列の指定が入れ替わっていることに注意してください。
テストの実行結果は、以下のようになります。
指定したデータの内容も確認できて、分かりやすいです。
パラメータの置換
上記で、set
コマンドを利用した変数の値の変換を実施しましたが、指定した変数の一部を置き換えるようなこと(例えば、文字列の一部分を変更した場合など)はできません。
そのような置換としては、別の方法があります。
replace
コマンドを利用すると、予め置換変数を指定しておき、それを指定した値で置換するようなことが可能です。
Scenario: Replace parameters
# デフォルトの置換変数 <val>
* def text1 = 'hello <foo> world'
* replace text1.foo = 'bar'
* match text1 == 'hello bar world'
# カスタムの置換変数 ${val}
* def text2 = 'hello ${foo} world'
* replace text2.${foo} = 'bar'
* match text2 == 'hello bar world'
# 複数のパラメータの置換
* def text3 = 'hello <val1> world <val2> bye'
* replace text3
| token | value |
| val1 | 'cruel' |
| val2 | 'good' |
* match text3 == 'hello cruel world good bye'
デフォルトの変数は、<val>
という形式です。この場合、```変数.val = 置換後の値```` のようなかたちで、変数の一部を置換できます。
置換パラメータは、形式をカスタマイズすることも可能です。${val}
のように定義して、置換することも可能です。この場合は、```変数.${val} = 置換後の値```` というかたちで置換します。
私は、どちらかというと、こちらの方が好みです。置換パラメータを指定する際に、こちらの方がパッと見た目で分かりやすい。
さらに、テーブル形式で、複数の置換パラメータを、まとめて置換することもできます。
ファイルからの読み込み
データの内容が大きい場合など、featureファイルの中で指定するのは、手間かもしれません。
そういう場合には、ファイルを読み込んで、利用することもできます。
Scenario: Reading files
* def sample01Json = read('sample01.json')
* print sample01Json
* match sample01Json == '#[7]'
* match sample01Json[0] == {color:'red', value:'#f00'}
* match sample01Json[6] == {color:'black', value:'#000'}
たった、これだけです。ファイルの読み込みも簡単ですね。
ただし、指定したファイルは、Karateを実行する際のクラスパスに含まれている必要があります。
まとめ
Karateのデータの定義方法を確認してみましたが、豊富な指定の仕方があり、また、それぞれほぼコマンドひとつで実現されており、簡単に定義できるのが良いと思っています。
テストシナリオを作成する上で、これらが変数などが簡単に指定できるのは、作業が効率的に進められるとお見ます。
より、詳しい使い方を調べる場合は、以下の Karate Demo を参照すると良いでしょう。
https://github.com/intuit/karate/tree/master/karate-demo