はじめに
前回は、KarateのExampleの内容を確認していきました。
今回は、実際に独自のテストシナリオを作成してみたいと思います。
テスト対象の構成
ここでは、シェアリングエコノミーサービスのひとつとして、レンタサイクルをイメージしたサービスのAPIを用意し、それに対して、テストシナリオを作成してみます。
サービスの構成は、以下のようなイメージになります。
- サービス条件
- 空き車両の一覧を確認することができます。
- 既に貸出されている車両は、さらに貸出することはできません。
テストシナリオ
シナリオ作成
以下の2つのテストシナリオを作成していきます。
シナリオ1
単純に、レンタサイクルの車両一覧を取得します。
シナリオというよりは、単にAPIを呼び出しているだけです。
No | 操作 | 確認内容 |
---|---|---|
(1) | レンタサイクルの車両一覧を取得する。 | 5台の車両が存在すること。 |
Karateのシナリオの内容は、以下になります。
Scenario: Get all rentacycles
Given path '/rentacycles'
When method get
Then status 200
And assert response.size() === 5
シナリオ2
空き車両を確認し、その車両のレンタル/返却を行います。
そのときの車両の状態を、適宜確認するようにします。
No | 操作 | 確認内容 |
---|---|---|
(1) | 空き車両の一覧を取得する。 | 3台の空き車両が存在すること(A001/A002/A003)。 |
(2) | 空き車両のひとつ(A001)を選択し、レンタルする。 | 結果が成功であること。 |
(3) | 空き車両の一覧を取得する。 | 2台の空き車両が存在すること(A002/A003)。 |
(4) | 既に貸出されている車両(A001)を、再度レンタルする。 | HTTPステータス409でエラーの応答が返ること。 |
(5) | レンタルした車両(A001)を返却する。 | 結果が成功であること。 |
(6) | 空き車両の一覧を取得する。 | 3台の空き車両が存在すること(A001/A002/A003)。 |
Karateのシナリオの内容は、以下になります。
Scenario: Rent / Return the cycle
# (1)空き車両一覧取得
Given path '/rentacycles'
And param available = true
When method get
Then status 200
And assert response.size() === 3
And match response contains {id: 'A001', rent: false}
And match response contains {id: 'A002', rent: false}
And match response contains {id: 'A003', rent: false}
# (2)レンタル処理
* def rentId = response[0].id
* print rentId
Given path '/rentacycles/rent'
And request {id: #(rentId)}
When method post
Then status 200
And match response ==
"""
{
result : true
}
"""
# (3)空き車両一覧取得
Given path '/rentacycles'
And param available = true
When method get
Then status 200
And assert response.size() === 2
# (4)レンタル処理(不可)
Given path '/rentacycles/rent'
And request {id: #(rentId)}
When method post
Then status 409
# (5)返却処理
Given path '/rentacycles/return'
And request {id: #(rentId)}
When method post
Then status 200
And match response ==
"""
{
result : true
}
"""
# (6)空き車両一覧取得
Given path '/rentacycles'
And param available = true
When method get
Then status 200
And assert response.size() === 3
シナリオ作成時のポイント
今回のシナリオでは、以下のようなところがポイントになります。
And match response contains {id: 'A001', rent: false}
And match response contains {id: 'A002', rent: false}
And match response contains {id: 'A003', rent: false}
- 「And」で条件を結合しています。
- 「match response contains xxx」で、レスポンスに含まれているデータを確認しています。
また、ここでお気づきでしょうか?
JSONの変数名の部分は、シナリオファイル内で、直指定しており、クウォート/ダブルクウォートで囲む必要がありません。
これにより、可読性も上がりますし、囲む操作が不要な分、変数の指定などが楽なります。地味ですが、便利な仕様だと思います。
もちろん、データ部分で文字列の場合は、クウォート/ダブルクウォートで囲んでくださいね。
* def rentId = response[0].id
- 直前のレスポンスで、最初の要素の「id」パラメータを取得し、それを変数に格納しています。
And request {id: #(rentId)}
- 先の内容で変数に保持した値を、「#(rentId)」という記述で、リクエストに指定しています。
テスト実行
テストに利用するソースコードは、以下に登録してあります。
事前準備
テスト対象のAPIが必要になりますが、WireMock を利用して、API側をモック化して呼び出せるようにしています。
以下の配下のmainをクラスを起動することで、モックサーバーが立ち上がるようにしています。
IDEなどを利用して、起動してください。
テスト実行
Karateのテストは、以下のコマンドで実行できます。
$ mvn clean test -Dtest=RentaCyclesRunner
テスト結果
テスト結果のレポートは、以下のディレクトリにHTML形式で出力されます。
- target/surefire-reports/TEST-examples.rentacycles.rentacycles.html
APIの内容は、同じAPIでも実行時の状態によって、レスポンスの内容が変わります。
今回のテストでは、その内容が確認できています。
レポートの内容で、リクエスト/レスポンス(青字の部分)は、実行時の内容を確認できるので、エラーが発生している場合などの原因調査にも役立ちます。
まとめ
実際に、テストシナリオを作成してみましたが、Karateでは、REST-APIを実行/確認するための便利な機能が豊富に用意されており、大きな手間なく、シナリオを作成できました。
以下のような点は、シナリオを作成するのに役立つ内容ですね。
- リクエスト/レスポンスを処理するための関数/変数がデフォルトで用意されている。
- 変数などを扱うことができ、前のレスポンスのデータを活用することも可能である。
- assertの内容も、柔軟に指定可能である。