karateでREST APIのテストをする。REST-Assuredとのソース比較も
はじめに
Web UIとREST APIのテストフレームワークを探しているときにkarateという、とても興味のそそられるフレームワークを見つけたので使い方や便利なところをまとめます。
環境
- IntelliJ:2020.1.3
- Java:11
- Gradle:7.0
環境作成
IntelliJのインストール
IntelliJのインストール
公式のホームページからインストーラーをダウンロードしてインストールしてください。
プロジェクトの作成
ファイルタブ > 新規 > プロジェクト を選択してプロジェクト作成ウィンドウを開いてください。
Gradle > Java を選択してJavaプロジェクトの作成
これでプロジェクトの作成が完了しました。
必要なライブラリの追加
build.gradleにコンパイル時のkarateの追加とJUnit platform を使う設定をします。
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
を下のように修正してください。
test {
useJUnitPlatform()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile 'com.intuit.karate:karate-junit5:1.0.1'
testImplementation('org.junit.jupiter:junit-jupiter')
}
スクリプトパスの追加
featureファイルを読み込ませるために、テストパスの場所を追加します。
sourceSets {
test {
resources {
srcDir file('src/test/java')
exclude '**/*.java'
}
}
}
テストソースの作成
karateは、テスティングフレームワークと組み合わせて使用します。今回はJUnit5と組み合わせます。
基本的にJUnitがJavaファイルを認識して、Javaファイルからテスト内容の書かれているfeatureを読み取りテストを実行します。
Javaファイルの作成
JUnitから読み込まれるJavaファイルを作成します。
package com.karate.api;
import com.intuit.karate.junit5.Karate;
// JUnitに読み込ませる関数を定義
class PetsTest {
@Karate.Test
Karate petsTest() {
// pets.featureを読み取るように定義
return Karate.run("pets").relativeTo(getClass());
}
}
featureファイルの作成
実際のテストコードをfeatureファイルに記載していきます。ファイルの場所は上のクラスファイルと同じディレクトリにしてください。今回は例としてhttp://localhost:8081/Petsのテストをしています。
Feature: sample karate test script
# ここにテスト対象のURLを指定
Background:
* url 'http://localhost:8081'
Scenario: pets get request
# urlのパスを指定
Given path 'Pets'
# GETメソッドを定義
When method get
# 戻り値がhttpステータス200であることのチェック
Then status 200
# 戻り値のデータのチェック
And match $ == [{"name":"pochi", "age": 2, "kind": "dog"}]
Scenario: pets get request add param
Given path 'Pets'
# queryパラメータの設定。/Pets?kind=cat&name=tama
And param kind = 'cat'
And param name = 'tama'
When method get
Then status 200
And match $ == [{"name":"tama", "age": 4, "kind": "cat"}]
Given path 'Pets'
# queryパラメータの設定。/Pets?kind=dog&name=tama
And param kind = 'dog'
And param name = 'tama'
When method get
Then status 200
And match $ == [{"name":"tama", "age": 2, "kind": "dog"}]
Scenario: pets post request
Given path 'Pets'
# リクエストボディの設定
And request [{"name":"pochi", "age": 2, "kind": "dog"}]
# POSTメソッドを定義
When method post
Then status 200
And match $ == [{"name":"pochi", "age": 2, "kind": "dog"}]
テストの実行
この2つでテストのソースを書くことが出来ました。
さっそく実行してみます。実行はgradleコマンドからもできますが、せっかくなのでIntelliJのGUIからやってみます。
Gradleウィンドウの表示
Gradleウィンドウが表示されていないときは、Gradleと書かれたところをクリックしてください。
テストの実行
Gradleウィンドウが表示されたらVertificationを開いてtestを選択してください。ここでtestがなかったり、エラーが出た場合はGradleの更新ボタンを押してください。
テストの結果確認
テストが正常に終了すると下のコンソールにpassと出るのでそれを確認します。
テストの個別結果の表示
上の例だとすべてのテスト結果が1つにまとめられていてわかりにくい場合もあるので、別の方法を紹介します。
IntelliJ上でソースやフォルダを右クリックして実行を選択するだけです。そうすることで下のように個別結果が表示されます。
さらに、プロジェクトルート/target/karate-reports配下にレポートが出力されています。
REST-Assuredとのソースの比較
REST APIのテストライブラリで有名なものとしてはREST-Assuredがあります。これとkarateを比較してみて、karateがわかりやすいのか確認してみます。
それぞれのソースコード
REST-Assured
RestAssured.baseURI = "http://localhost:8081";
given()
.when()
.get("/Pets")
.then()
.statusCode(200)
.body("name", equalTo("pochi"))
.body("age", equalTo(2))
.body("kind", equalTo("dog"));
karate
Feature: sample karate test script
Background:
* url 'http://localhost:8081'
Scenario: pets get request
Given path 'Pets'
When method get
Then status 200
And match $ == [{"name":"pochi", "age": 2, "kind": "dog"}]
感想
REST-Assuredは9行、karateは8行と書く量としてはそれほど変わりませんでした。ソースの見やすさとしてはJavaになれている人はREST-Assuredの方が見やすいのかなと思います。Javaになれていない人やインタフェースしか決めていない人にとってはkarateの方が見やすいのかなと思います。
REST-Assuredは関数の指定方法がJavaっぽい上に、いかにもプログラミングという見た目をしているのでJavaになれていない人にとっては取っつきにくいかと思います。一方でkarateは定義ファイルを記載するような見た目なのである程度システムを知っている人ならば取っつきやすいかと思います。
独自関数の使用
ここまでまとめて、featureとJavaでファイルが違うのでJavaで書いた独自関数を使用しにくいので純粋なJavaを使用したライブラリの方が良いという人もいるかもしれません。そこらへんもkarateは考慮していて簡単にJava関数をfeatureファイル内で使用することができます。
Javaでの独自関数の作成
例としてDBにQueryを発行する関数を作成します。
package karate;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
public class DbUtils {
private final JdbcTemplate jdbc;
public DbUtils() {
ResourceBundle bundle = ResourceBundle.getBundle("application");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl(bundle.getString("spring.datasource.url"));
dataSource.setUsername(bundle.getString("spring.datasource.username"));
dataSource.setPassword(bundle.getString("spring.datasource.password"));
jdbc = new JdbcTemplate(dataSource);
}
public Object readValue(String query) {
return jdbc.queryForObject(query, Object.class);
}
public Map<String, Object> readRow(String query) {
return jdbc.queryForMap(query);
}
public List<Map<String, Object>> readRows(String query) {
return jdbc.queryForList(query);
}
}
featureからのJava関数の呼び出し
例としてDBにQueryを発行する関数を作成します。
Background:
* url 'http://localhost:8081'
# 読み取るJavaのファイルを読み込む。karateフォルダ内のDbUtilファイルを読み込む
* def DbUtils = Java.type('karate.DbUtils')
# インスタンスを生成する
* def db = new DbUtils()
Scenario: pets post request
Given path 'Pets'
And request [{"name":"pochi", "age": 2, "kind": "dog"}]
* def post_petId = response.id
# SQL発行してDBから情報取得
* def pets = db.readRows('SELECT * FROM Pets WHERE id="' + post_petId + '"')
# DBとリクエストしたデータの比較
And assert pets[0].name == "pochi"
And assert pets[0].kind == "dog"
終わりに
開発をするときは、ある程度Javaのことを理解しているのでkarateをREST APIのテストだけに使う場合は、そこまでメリットを感じないです。どちらかと言うと個々の機能だけを抽出して使用するのではなく、REST API・モック・UIと複数のテストにkarateを導入することで総合的に学習コストを下げたり、ソース間の統一を図りきれいなソースにするというところを期待するのかなと思います。他にも人の入れ替えが多く、Javaに対する知識が少ない人が入ってくる可能性の高いプロジェクトだとテスト作成の人手としてJavaの知識がない人も考慮にいれることができるため、導入する意味はあるのかと思います。
Author And Source
この問題について(karateでREST APIのテストをする。REST-Assuredとのソース比較も), 我々は、より多くの情報をここで見つけました https://qiita.com/mink0212/items/872893202449a0a42776著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .