テストツール「Karate」を使ってAPIテストに入門しよう

ノッパクン
ノッパクン

こんにちは。不健康な食生活が続いていて、健康診断の結果におびえる日々を送っています。どうもノッパクンです。

最近はAPIテストにハマってます。紹介したいテストツールはいくつかあるんですが、その中の1つ「Karate」を紹介いたします。

Karateとは

APIテスト、GUIテスト、性能テストなど、各種テストを幅広くサポートしている総合的なツールとなります。

魅力はなんといっても多機能な点です。他のテストツールと比較して痒い所に手が届くなぁという印象があります。

本記事ではKarateのAPIテストのみに焦点をあて、入門編という事で紹介していきます。
ぜひ最後までお付き合いください。

導入

Karateを実行するにあたり、以下のものをインストール・ダウンロードしましょう。
今回はすぐに実行できるZIP版のKarateを使用してサクッといきたいと思います。

$ java -version
java version "18.0.1.1" 2022-04-22
Java(TM) SE Runtime Environment (build 18.0.1.1+2-6)
Java HotSpot(TM) 64-Bit Server VM (build 18.0.1.1+2-6, mixed mode, sharing)

JDKインストール後は以下のコマンドを実行してJavaのバージョンが表示されるか確認しましょう!

Javaコマンドが実行できない場合、「Java パスを通す」でググると記事がたくさん出ると思いますのでそちらを参照して対応をお願いします。ここでは割愛します。

ひとまずお試し

実行

準備が整ったら早速実行していきましょう!
karate-x.x.x.zipを展開してVSCodeで開くと以下のようなプロジェクト構成になっているかと思います。

└─karate-1.2.0
    └─src
        └─demo
            ├─api ★
            ├─mock
            ├─robot
            └─web

★配下に既に2つのAPIテストファイルが配置されているので、そのうちの1つ「httpbin.feature」を実行してみましょう。
ファイルを開いたら、上部の「Karate: Run」をクリックで実行します。(一旦内容はスルーします)

無事APIが実行され、以下のような実行結果が表示されました。

======================================================
elapsed: 4.46 | threads: 1 | thread time: 2.99
features: 1 | skipped: 0 | efficiency: 0.67
scenarios: 1 | passed: 1 | failed: 0
======================================================

レポートの確認

実行結果はhtmlファイルでも出力されます。以下の★配下にある「karate-summary.html」が直近の実行結果レポートになるので確認してみましょう!

└─karate-1.2.0
    ├─src
    │  └─demo
    │      ├─api
    │      ├─mock
    │      ├─robot
    │      └─web
    └─target
        ├─karate-reports ★

シンプルにまとめられていて結果が確認がしやすいですね。シナリオごとに合否がカウントされています。

色々さわってみよう

それでは、.featureファイルを新たに作成して色々なAPIテストを試してみましょう。
テスト対象のAPIとして以下のダミーAPIを使用します。

シンプルGET

trial.featureファイルを作成してそこにリクエスト内容を記載していきます。

Feature: trial
  Background:
    * url 'https://jsonplaceholder.typicode.com' [1]

Scenario: simple get
  Given path 'posts/1' [2]
  And header Accept = 'application/json' [3]
  When method get [4]
  Then status 200 [5]
  • [1] リクエスト先のベースURLを指定
  • [2] リクエスト先のパスを指定
  • [3] ヘッダーを追加
  • [4] GETメソッドを使用
  • [5] 期待するレスポンスのステータスコード

実行してみると・・・、上手くいってますね!
以降は同一のファイルにシナリオ単位で追記していきます。(実行結果は省略)

シンプルPOST

Scenario: simple post
  Given path 'posts'
  And header Accept = 'application/json'
  And header Content-Type = 'application/json' [1]
  And request { title: 'This is Karate!!!' } [2]
  When method post
  Then status 201
  • [1] ヘッダーを追加
  • [2] ボディを追加

↓内容が多い場合はこのように記載すると楽です。

Scenario: simple post
  Given path 'posts'
  And header Accept = 'application/json'
  And header Content-Type = 'application/json'
  And request 
    """
      {
    title: 'This is Karate!!!' 
      }
    """
  When method post
  Then status 201

レスポンス内容を次のリクエストに使用する

GETで取得したアイテムのタイトルを、次のPOSTのボディで使用します。
GETとPOSTは先ほど作成した内容を流用しています。

Scenario: response to request
  Given path 'posts/1'
  And header Accept = 'application/json'
  When method get 
  Then status 200

  * def title = response.title [1]

  Given path 'posts'
  And header Accept = 'application/json'
  And header Content-Type = 'application/json'
  And request {title: #(title)} [2]
  When method post
  Then status 201
  • [1] 変数を定義&レスポンスのタイトルを代入
  • [2] 変数を使用

リトライ実行

APIがタイムアウトを起こしてしまうなど、リトライを設定すると便利なシチュエーションはあるかと思います。リトライはリクエスト単位で設定可能です。

Scenario: retry

* configure retry = { count: 10, interval: 1000 } [1]

  Given path 'posts/1'
  And header Accept = 'application/json'
  And retry until responseStatus == 200 [2]
  When method get 
  Then status 200
  • [1] リトライ設定
    • リトライの回数とインターバル(ms)を設定します
    • 省略すると、デフォルト3回リトライ・3秒間インターバルが適用されます
  • [2] リトライ条件
    • ステータスコード200が返却されるまでリトライします

ためしに`responseStatus == 201`などに変更するとリトライを確認できます。

CSVファイル読み込み(DDTデータ駆動)

csvファイルの1行1行でシナリオをループさせる事ができます。この機能により、テストだけに限らず、データ挿入のツールとしても使えそうです。

まず「data.csv」を作成して、trial.feature と同じディレクトリに配置します。
csvの先頭行がそのまま変数名として使用できます。

id
1
2
3
4
5

次にリクエストを作成します。

Feature: trial
  Background:
    * url 'https://jsonplaceholder.typicode.com'
    * def csv = read('data.csv') [1]
    
~~~~~

Scenario Outline: ddt [2]

  Given path 'posts/<id>' [3]
  And header Accept = 'application/json'
  When method get 
  Then status 200

  Examples: [4]
    |csv|
  • [1] csvファイル読み込み
  • [2] `Outline`追記(おまじない)
  • [3] 変数を使用
  • [4] 使用データ宣言

実際にはファイル読み込み時にcsvがJsonに変換され、JsonをExamplesに渡す流れになってます。

ログ出力

ログは以下のように出力します。

  Scenario: log

    * print '★任意の場所に'
    Given path 'posts/1'
    And header Accept = 'application/json'
    * print '★ログを'
    When method get 
    Then status 200
    * print '★出力できます'

結果にも表示されてますね。

お疲れ様でした

Karateは他にもたくさんの機能があります。公式のGitHubに目を通してみると、お気に入りの機能が見つかるかもしれません。

ノッパクン
ノッパクン

私自身もKarateをたくさん使って、次の健康診断に備えたいと思います。

それでは、素敵なKarateライフを~!