この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
APIを継続的に開発/デプロイをしていると、単体テストでは全て正常なのに複数のAPIを特定のシナリオで実行したときに異常が起きるケースがありますよね。これを自動で検知するために、PostmanのCLI runnerであるnewmanとCircleCIで定期的にAPIのシナリオテストを自動で行う仕組みを作ってみました。
TL;DR
- PostmanのCollectionはnewmanというCLIのrunnerで実行できるよ
- CircleCIの2.1でサポートされたOrbsとSchedule機能が便利だよ
- 同じことをPostmanのMonitorsからもできるけどnewmanの方が便利な場合もあるよ
環境
- MacOS: 10.14.5
- Node: v10.15.3
PostmanのCollectionを作成する
まずはPostmanでCollection(テストケースの集まり)を作ります。
この記事ではサンプルとして Postman Echo のCollectionを利用させてもらいます。
- ページ右上の
Run in Postman
ボタンから、PostmanのクライアントアプリにCollectionをインポートします。クライアントアプリがインストールされていない場合は、先にインストールをします。 - Postmanのクライアントアプリで、インポートしたCollectionを
Run
で実行して、テストが実行されることを確認します。テストが全部成功しなくても手順の確認としては問題ありません。 - Postmanのクライアントアプリで、インポートしたCollectionを
Export
します。ファイル名をcollection.json
とします。
newmanでCollectionを実行する
- newmanを
npm install -g newman
でインストールします。 newman run ./collection.json
でテストが実行されることを確認します。
CircleCIでnewmanを使ってCollectionを実行する
CircleCIでnewmanを使う方法は、この記事に詳しく書いてあります。
Set up a CircleCI pipeline to run a Postman collection using the Newman orb
この記事ではCircleCI 2.1から導入されたOrbsという「ある特定の処理を実行するための環境やコマンドがまとめられたパッケージのようなもの」を使っています。PostmanがCircleCIでnewmanを実行するために公式で提供しているOrbがこちらです。
OrbはCircleCI 2.1から導入された機能なので、configも2.1の記法に従う必要があります。まだキャッチアップされてない場合は、こちらの記事を読むと良いです。
あと、Orbsを使うために、CircleCIの設定を2点変更する必要があります。
- リポジトリの設定の Settings >> Advanced Settings にて、Enable pipelinesをOnにします。
- 全体の設定の Settings >> security にて、3rd PartyのOrbの使用を許可します。
それではサンプルプロジェクトを作成してCircleCIでCollectionを実行してみましょう。
プロジェクト構成
.
├── .circleci
│ └── config.yml
└── postman
└── collection.json
.circleci/config.yml
version: 2.1
orbs:
newman: postman/newman@0.0.2
workflows:
commit:
jobs:
- newman-collection-run
jobs:
newman-collection-run:
executor: newman/postman-newman-docker
steps:
- checkout
- newman/newman-run:
collection: ./postman/collection.json
GitHubにCommitをPushして、CircleCIのジョブが実行されました。
#!/bin/sh -eo pipefail
newman run ./postman/collection.json
newman
Postman Echo
❏ Request Methods
↳ GET Request
GET https://postman-echo.com/get?foo1=bar1&foo2=bar2 [200 OK, 629B, 115ms]
✓ response is ok
✓ response body has json with request queries
↳ POST Raw Text
POST https://postman-echo.com/post [200 OK, 658B, 7ms]
✓ response is ok
✓ response body has json with request body
(中略)
┌─────────────────────────┬──────────────────┬─────────────────┐
│ │ executed │ failed │
├─────────────────────────┼──────────────────┼─────────────────┤
│ iterations │ 1 │ 0 │
├─────────────────────────┼──────────────────┼─────────────────┤
│ requests │ 37 │ 0 │
├─────────────────────────┼──────────────────┼─────────────────┤
│ test-scripts │ 37 │ 0 │
├─────────────────────────┼──────────────────┼─────────────────┤
│ prerequest-scripts │ 0 │ 0 │
├─────────────────────────┼──────────────────┼─────────────────┤
│ assertions │ 90 │ 9 │
├─────────────────────────┴──────────────────┴─────────────────┤
│ total run duration: 4.3s │
├──────────────────────────────────────────────────────────────┤
│ total data received: 12.58KB (approx) │
├──────────────────────────────────────────────────────────────┤
│ average response time: 98ms [min: 4ms, max: 2s, s.d.: 325ms] │
└──────────────────────────────────────────────────────────────┘
# failure detail
1. AssertionError response body has json saying passed 'status'
expected { Object (message) } in response to contain property 'status'
at assertion:1 in test-script
inside "Authentication Methods / Hawk Auth"
2. AssertionError response has chunked transfer encoding header
expected response to have header with key 'transfer-encoding'
at assertion:1 in test-script
inside "Utilities / Streamed Response"
(中略)
Exited with code 1
失敗したテストケースがあると終了コードが1になるので、CircleCIのジョブも失敗します。
GraphQLの場合
ここまでの内容は一般的なAPIでしたが、私がやりたかったのはGraphQLのテストでした。実はPostmanは最近のアップデートでGraphQLに正式に対応しました。(いままでもリクエストのBodyを頑張って書けばできたけど、頑張らなくて良くなりました。)
私はこれを使っており、これで作ったCollectionをOrbの postman/newman@0.0.2
で実行してみたのですが、newmanのバージョンが古いためか正しく動きませんでした。なのでOrbは使わず、普通にnpmで最新のnewmanをインストールして実行するように、以下のようにconfigを修正しました。
version: 2.1
# orbs:
# newman: postman/newman@0.0.2
executors:
node10-executor:
docker:
- image: circleci/node:10.10-stretch
workflows:
commit:
jobs:
- newman-collection-run
jobs:
newman-collection-run:
# executor: newman/postman-newman-docker
# steps:
# - checkout
# - newman/newman-run:
# collection: ./postman/collection.json
executor: node10-executor
steps:
- checkout
- run: sudo npm install -g newman
- run: newman run ./postman/collection.json
CircleCIのジョブを定期的に実行する
あとはこのジョブを定期的に実行するようにします。これもCircleCI 2.1からの機能で、コミットしなくてもスケジューラによりジョブを起動できるようになりました。
例えば、ジョブを毎日00:00(JST)に実行させたい場合は、configを以下のように修正します。
workflows:
# commit:
# jobs:
# - newman-collection-run
nightly:
jobs:
- newman-collection-run
triggers:
- schedule:
cron: "00 15 * * *" # UTC
filters:
branches:
only:
- master
Appendix: Postman(web)でCollectionを定期的に実行する
ところで、一通りの検証が終わってから気づいたのですが、PostmanのWebコンソールを使うとMonitorという機能でCollectionを定期的に実行することができるんですね。フリープランだと回数制限が少なかったり通知の手段がメールだけだったりと制約はあるものの、用途によってはこちらで十分な場合もあるかと思います。
ちなみにGraphQLのCollectionも現時点(2019/07/04)では対応していませんでしたが、直に対応するでしょう。
おわりに
今回の検証で改めてPostmanを色々調べてみてまだ使ってない便利機能がありそうなので、有料プランも視野にプロジェクトでの活用を検討したいと思いました。あとCircleCIの2.1はかなり良いアップデートなので全部のリポジトリのconfigをバージョンアップしたいと思いました。