Apidogの自動テストを試してみた

## はじめに
bravesoft 株式会社でサーバサイドエンジニアをしているみっちーです。
今まで開発を続けている中で、APIレベルでの自動テストを行いたいという気持ちはありつつもなかなかできていなかったのですが、API開発ツールとして使っている Apidog にその機能があったので、実際に使ってみることにしました。

https://apidog.com/jp/

## そもそも Apidog を使うようになったきっかけ
私の開発チームでは、もともとバックエンド担当者が Swagger で API のドキュメントを作り、HTML出力したあとでフロントエンド担当者へ渡すという運用を取っていました。
APIドキュメントの修正が発生した場合に都度ビルドしないといけないなど手間に感じていたなかふと Apidog を知り、ドキュメントを書いてリアルタイムに共有しつつ、そのまま実行もできるということで試しに使ってみることにしました。
また、書いたドキュメントを元にそのままテスト実行ができるのも大きなメリットに感じました。
Apidog 自体についてや他のツールと比べたメリットについては、すでに書かれた記事がいくつかあるので、ここでは割愛します。

## テスト対象
現在開発が大詰めに入っている弊社の新規プロダクトである「イベスタ」の API でやっていきたいと思います。
イベントサイト制作やチケット販売を今すぐ無料でカンタンに始められ、オフ会イベントや音楽ライブ、ビジネスセミナー、大学生のタコパまで、誰でも気軽に開催できるイベントスタートサービスとなっています。

https://evesta.eventos.tokyo/

## 自動テストの作成方法
:::note info
API のパスやパラメータなどはダミーで、実際のものとは異なります。
:::

Apidog の左側のメニューある「自動テスト」を選択し、「テストシナリオを新規作成」ます。
![qiita_apidog_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/3ba53071-f0ef-838b-1db2-aa921c2c364d.png)

テストシナリオの名称をつけます。
今回はイベスタでイベントを作成してコンテンツなどを追加して、削除するまでの一連の流れをテストしてみたいと思います。
![qiita_apidog_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/0d49c78a-a26c-f204-158b-31839bad900e.png)

ステップを追加から、実行したい API を設定します。
ここではすでに定義済みの API を選びましたが、開発時にテスト実行用として用意した APICase の参照、また新たにリクエストを定義したり cURL をインポートしたりすることもできます。
Apidog で管理していない API を実行する際は、cURL からインポートすると便利かと思われます。
![qiita_apidog_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/90512678-7503-755f-e8b6-ce7c65309d2f.png)

自動テストを実施するうえで動的値を扱うことは必須かと思いますが、 Apidog ではそれを視覚的かつ簡単に設定することができました。
下記赤枠のボタンをクリックすると色々と選択肢が出てくるので、「前置きステップの結果を読み込み」をクリックします。
![qiita_apidog_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/4f741c60-a018-aa3b-e74d-0bc23c3dcc01.png)

自身の API よりも前に実行した API の一覧が選択できるのでその中から対象の API を選び、JSONPath 式で参照したい値を指定します。
この時赤枠のボタンをクリックすると、定義済みのレスポンスから例を自動生成してくれます。
![qiita_apidog_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/327722b0-86f9-8a0a-6742-6a6ff2460f57.png)

ここで表示される値は適当ですが、「JSONパスを抽出」ボタンをクリックすることで、対象データまでのパスを取得することができます。
![qiita_apidog_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/a17057f8-974f-f004-3192-d63cd5ca4bc1.png)

パラメータは `{{$.1.response.body.data.event_id}}` と出力されました。
`{{$.[APIの実行順番号].response.body.[目的の値までのパス]}}` という形式のようです。
![qiita_apidog_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/187fd3e3-66f7-87a5-14d0-466e6f3580f1.png)

上記はパスパラメータの例ですが、body の中にも同様に設定することができます。
![qiita_apidog_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/59b9bba7-bb04-55b3-2221-d21aaa6d255b.png)

最終的に下記のようなシナリオとなりました。
![qiita_apidog_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/79d075b6-0ad3-2641-55a8-ad2f56096ad5.png)

## 自動テストの実行
テストの実行は右上の「実行」ボタンから行うことができます。
![qiita_apidog_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/756a01f5-8a66-91f4-069d-5876b11d6624.png)

実行結果はこのように表示されます。
![qiita_apidog_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/5d3303b1-6a4d-4e6d-be3c-6666afb7c3ab.png)

レポートをエクスポートすることもできました。
HTMLファイルがダウンロードされ、開くと下記のようなページでまとまっていました。
「API Request状況」には、実行した API が一つずつ列挙されています。
![qiita_apidog_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/9f5f805d-3511-fe92-1e15-800ac9dcbdd6.png)

## 失敗させてみる
テストが失敗した場合の動きも見てみます。
ここでは、イベント主催者の電話番号を `tel` というキーで返すはずが、なぜか `telephone` にしてしまったケースを想定します。
実行したところ、該当データ取得の API 1件でエラーになりました。
該当業をクリックすると詳細を見ることができ、`tel` のキーが存在しないというエラーだと表示されました。
![qiita_apidog_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938191/98f0b484-e2ad-6343-69dc-96e1aeefd34c.png)

ここで注目したいのが、レスポンスのステータスコードとしては 200 であるかつ、テストの期待値を明示的に書いていないのにエラーを検知した点です。
Apidog 側で正しくレスポンスの定義をしていれば、たとえ 200 が返ってきた場合であっても定義と反するレスポンスだった場合に、不正な状態を検知することができます。
この点は大きなメリットかなと感じました。

## まとめ
今回は Apidog の自動テストについて実際に使いつつ調査してみました。
テストシナリオの作成にはそれほど手間取らず、APIドキュメントを作った延長線上で自動テストができるということはやはり大きなメリットに感じました。
また実際に試せてはいないものの、Github Actions などの CI/CD とも連携できるようなので、更に便利に使うことができそうです。
Apidog 自体まだベータ版や近日公開の機能もあるので、動向を追いつつも引き続き積極的に使っていきたいと思います。