test
rest
REST-API
Karate

Karate入門:Karateを使ったREST APIテスト

ご挨拶

この記事は ピクシブ株式会社 AdventCalendar 20176日目の記事です。

2017/11に中途入社したshimashima35と申します。10年以上サーバサイドJavaの開発をしつつソフトウェア工学・品質の勉強をしてきて、前職からQA/SET(Software Engineer in Test)/DevQA として品質に関わるようになりました。ピクシブでは技術基盤チームというところに所属し、テストや品質に関わる部分で様々なプロダクトに関わって行きます。
好きなRFCはRFC3514です。ちゃんと実装されたのが味噌です。

はじめに

以前、REST APIをテストするためのツールとして REST Assuredを紹介(その1,その2)しましたが、今回は同じREST APIをテストするための別のツール(フレームワーク)であるKarateについて簡単に紹介して行こうと思います。

Karateとは

Karateとは、アメリカオンライン会計システム最大手であるIntuitがGitHub上で開発しているREST API向けテストフレームワークです。以前紹介したREST Assuredは、Javaで実装されメソッドチェインを用いたDSLでテストを記述するものでしたが、KarateはCucumber-jvm1上にREST APIテスト向けのDSLを実装・提供しGherkin2の文法を使うことで自然言語に近い形でテストを記述して行きます。
ライセンスはMITなので比較的安心して使えます。

使い方

前提条件

以下の環境で試しました。

ソフトウェア 説明 バージョン
OS(macOS) HighSierra 10.13.1
Java 言語プラットフォーム 9.0.1
Apache Maven ビルドツール 3.3.9(IntelliJ IDEA組み込み)
Karate 今回のターゲットであるREST APIテストフレームワーク 0.6.1
JUnit テストライブラリ 4.12

公式ではJava8となっていますが、今ところJava9でも問題ありません。

pom.xml作成

まずmaven用のpom.xmlを作成します。KaraterとJUnitへの依存を追加するために以下を追記します。

    <dependency>
        <groupId>com.intuit.karate</groupId>
        <artifactId>karate-apache</artifactId>
        <version>0.6.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.intuit.karate</groupId>
        <artifactId>karate-junit4</artifactId>
        <version>0.6.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

次に、推奨ディレクトリ構成のために、build要素を以下のようにします。

   <build>
     <testResources>
       <testResource>
         <directory>src/test/java</directory>
         <excludes>
           <exclude>**/*.java</exclude>
         </excludes>
       </testResource>
     </testResources>
  </build>

Karateでは、Javaで記述しJUnitからキックされるTestRunnerとGherkinの文法で記述するfeature両方をsrc/test/java配下にすることが推奨されています。上の記述がないとsrc/test/java配下のファイルはテスト実行時に参照されるclasspathに含まれない(test-classesディレクトリに移動しない)ための対策です。

Runner作成

JUnitから起動されるTestRunnerクラスを作成します。
今回の例では役にたちませんが、Karateのサンプルに則り基底クラスも作成します。

TestBase.java
package jp.dip.prog;

import com.intuit.karate.junit4.Karate;
import org.junit.runner.RunWith;

@RunWith(Karate.class)
public abstract class TestBase {

}
SampleRunner.java
package jp.dip.prog;

import cucumber.api.CucumberOptions;

@CucumberOptions(features = "classpath:jp/dip/prog/sample.feature")
public class SampleRunner extends TestBase {
}

@RunWith(Karate.class)でKarateを起動させることをあらわします。また@CucumberOptions(features = "classpath:jp/dip/prog/sample.feature")でRunnerから実際に実行されるFeatureをクラスパスから指定します。

config作成

Karateで共通で使う設定を記述するファイルを作成します。この後で説明するfeatureファイルに個別で定義することもできるようですが、共通部分はconfigとしてまとめると便利です。
ファイル名はkarate-config.js固定で、src/test/java直下に配置します。

karate-config.js
function() {
  karate.configure('connectTimeout', 5000);
  karate.configure('readTimeout', 5000);
  return { demoBaseUrl: 'http://jsonplaceholder.typicode.com' };
}

これで、各種タイムアウトおよびURLのベース部分が指定されました。

feature作成

最後に実際のテストしたい内容を記述するfeatureファイルを作成します。
ここではGherkinの文法を使いKarate独自に定義したDSLで記述して行きます。
Karateで使える語彙は公式サイトを参照するとよいようです。私も最低限の語彙しか確認していません。

以前のREST Assuredでのサンプルと同じ動きをさせるfeatureを以下にように書きます。

sample.feature
Feature: calling sample rest api

Background:
    * url demoBaseUrl

Scenario: get id = 2

Given path 'posts/2'
When method get
Then status 200
And assert response.userId == 1
And assert response.id == 2
And assert response.title == "qui est esse"
And print response

Karateが初めてであっても、なんとなく使い方は想像できるのではないでしょうか。
GivenでURLを、Whenでメソッド指定、ThenおよびAndで結果に対する処理を記述していきます。
Responseの解析はJSONとXMLがデフォルトで行えるようになっています。上記の例も実際のResponseはJSONですが、適切にパースして処理してくれています。

GitHub

ここで作成したファイル一式をGitHubのリポジトリにあげましたので参考にしてください。

おわりに

本当に簡単にKarateの最低限の使い方を説明してきましたがいかがだったでしょうか。比較的簡単に、ノンプログラマでもテストがかけるよう工夫されていることがわかったのではないでしょうか。
まだバージョンが0.6.1とまだまだ成長する余地があるようですし、GitHub上で活発に開発が進んでいるのでこれからが楽しみなプロダクトではないでしょうか。


  1. CucumberというBDD(ビヘイビア駆動開発)を行うためのフレームワークをJavaVM上に移植したものです。詳細はリンク参照。 

  2. Cucumberで検証内容を記述するための文法。Feature, Scenario, Given, When, Then などの単語をもちいて表現する。詳細はリンク参照。