空手によるRESTAPIテスト
1. 概要
この記事では、Javaのビヘイビア駆動開発(BDD)テストフレームワークである空手を紹介します。
2. 空手とBDD
空手は別のBDDテストフレームワークであるCucumberの上に構築されており、同じ概念のいくつかを共有しています。 これらの1つは、テストされた機能を説明するGherkinファイルの使用です。 ただし、Cucumberとは異なり、テストはJavaで記述されておらず、Gherkinファイルに完全に記述されています。
Gherkinファイルは、「.feature」拡張子で保存されます。 Feature キーワードで始まり、同じ行に機能名が続きます。 また、さまざまなテストシナリオも含まれており、それぞれがキーワードシナリオで始まり、キーワード Given 、 When 、Thenの複数のステップで構成されています。 、および、およびしかし。
キュウリとガーキン構造の詳細については、こちらをご覧ください。
3. Mavenの依存関係
MavenプロジェクトでKarateを利用するには、karate-apache依存関係をpom.xmlに追加する必要があります。
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-apache</artifactId>
<version>0.6.0</version>
</dependency>
JUnitテストを容易にするために、karate-junit4依存関係も必要です。
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-junit4</artifactId>
<version>0.6.0</version>
</dependency>
4. テストの作成
まず、Gherkin Featureファイルにいくつかの一般的なシナリオのテストを記述します。
4.1. ステータスコードのテスト
GETエンドポイントをテストし、 200 (OK)HTTPステータスコードを返すかどうかを確認するシナリオを作成してみましょう。
Scenario: Testing valid GET endpoint
Given url 'http://localhost:8097/user/get'
When method GET
Then status 200
これは明らかに、考えられるすべてのHTTPステータスコードで機能します。
4.2. 応答のテスト
RESTエンドポイントが特定の応答を返すことをテストする別のシナリオを書いてみましょう。
Scenario: Testing the exact response of a GET endpoint
Given url 'http://localhost:8097/user/get'
When method GET
Then status 200
And match $ == {id:"1234",name:"John Smith"}
一致操作は検証に使用されます。ここで、’$’は応答を表します。 したがって、上記のシナリオでは、応答が’ {id:” 1234”、name:” John Smith”}’と完全に一致することを確認します。
idフィールドの値を具体的に確認することもできます。
And match $.id == "1234"
一致操作を使用して、応答に特定のフィールドが含まれているかどうかを確認することもできます。これは、特定のフィールドのみを確認する必要がある場合、またはすべての応答フィールドがわかっていない場合に役立ちます。
Scenario: Testing that GET response contains specific field
Given url 'http://localhost:8097/user/get'
When method GET
Then status 200
And match $ contains {id:"1234"}
4.3. マーカーを使用した応答値の検証
返される正確な値がわからない場合でも、マーカー(応答の一致するフィールドのプレースホルダー)を使用して値を検証できます。
たとえば、マーカーを使用して、null値が必要かどうかを示すことができます。
- #ヌル
- #notnull
または、マーカーを使用して、フィールド内の特定のタイプの値に一致させることもできます。
- #boolean
- #番号
- #ストリング
フィールドにJSONオブジェクトまたは配列が含まれると予想される場合は、他のマーカーを使用できます。
- #配列
- #物体
また、特定の形式または正規表現に一致するマーカーと、ブール式を評価するマーカーがあります。
- #uuid —値はUUID形式に準拠しています
- #regex STR —の値が正規表現STRと一致します
#? EXPR — JavaScript式が EXPR に評価します真実
最後に、フィールドのチェックが不要な場合は、#ignoreマーカーを使用できます。
上記のシナリオを書き直して、idフィールドがnullでないことを確認しましょう。
Scenario: Test GET request exact response
Given url 'http://localhost:8097/user/get'
When method GET
Then status 200
And match $ == {id:"#notnull",name:"John Smith"}
4.4. リクエスト本文を使用したPOSTエンドポイントのテスト
POSTエンドポイントをテストし、リクエスト本文を受け取る最後のシナリオを見てみましょう。
Scenario: Testing a POST endpoint with request body
Given url 'http://localhost:8097/user/create'
And request { id: '1234' , name: 'John Smith'}
When method POST
Then status 200
And match $ contains {id:"#notnull"}
5. テストの実行
テストシナリオが完了したので、KarateをJUnitと統合してテストを実行できます。
@CucumberOptions アノテーションを使用して、Featureファイルの正確な場所を指定します。
@RunWith(Karate.class)
@CucumberOptions(features = "classpath:karate")
public class KarateUnitTest {
//...
}
REST APIを示すために、
この例では、@BeforeClassで注釈が付けられたメソッドでテストされているすべてのエンドポイントをモックします。 @AfterClassアノテーションが付けられたメソッドでWireMockサーバーをシャットダウンします。
private static WireMockServer wireMockServer
= new WireMockServer(WireMockConfiguration.options().port(8097));
@BeforeClass
public static void setUp() throws Exception {
wireMockServer.start();
configureFor("localhost", 8097);
stubFor(
get(urlEqualTo("/user/get"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{ \"id\": \"1234\", name: \"John Smith\" }")));
stubFor(
post(urlEqualTo("/user/create"))
.withHeader("content-type", equalTo("application/json"))
.withRequestBody(containing("id"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{ \"id\": \"1234\", name: \"John Smith\" }")));
}
@AfterClass
public static void tearDown() throws Exception {
wireMockServer.stop();
}
KarateUnitTest クラスを実行すると、RESTエンドポイントがWireMockサーバーによって作成され、指定された機能ファイル内のすべてのシナリオが実行されます。
6. 結論
このチュートリアルでは、KarateTestingFrameworkを使用してRESTAPIをテストする方法について説明しました。
この記事の完全なソースコードとすべてのコードスニペットは、GitHubのにあります。