🥇
REST API をワンコマンドでテストする環境をつくる
背景
- REST API のリファクタがしたい
- デグレがこわいので、かんたんにテストする環境がほしい
目標
- REST API をワンコマンドでテストする環境をつくる
- コマンドであれば、シェルや他のツールに組み込んで継続的テスト(continuous testing)環境を構築することも簡単になりそうなので
ポイント!
- ツールはstepciを使う(ツールは他にもあるが比較的新しそうだったので)
- stepciはnodejs v12以上が必要
- OpenAPI specからテストケースをつくると楽できる
stepciとは?
Step CI はオープンソースの API 品質保証フレームワーク
環境
- Ubuntu 20.04LTS
- 本当は、windowsに環境を作りたかったが、nodejsがエラーになることがあり一旦こちらで
手順
npmとnodejsをインストールする
sudo apt update
sudo apt install nodejs
sudo apt install npm
nodejsを更新する
Ubuntu 20.04LTSの場合、nodejsはv10がインストールされる。nodejsがv12より前だと後程インストールするstepciがエラーになるので、nodejsを更新する。
現在recommendedのv18に更新。
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\
sudo apt-get install -y nodejs
stepciをインストールする
以下、ローカルインストール想定。
適当なフォルダを作成して移動する。
mkdir ~/resttest
cd ~/resttest
stepciをインストールする。
npm init
npm install --save-dev stepci
テストケースを作成する
stepciをrunさせるためのテストケース(workflow.yml)を作成する。
./node_modules/.bin/stepci init
Success! The workflow file can be found at workflow.yml
Enter npx stepci run workflow.yml to run it
できた workflow.yml
version: "1.1"
name: Status Check
env:
host: example.com
tests:
example:
steps:
- name: GET request
http:
url: https://${{env.host}}
method: GET
check:
status: /^20/
↑GET https://example.com を実行した結果が'20'で始まるステータス(200や201や202など)であることを確認するという意味。
もし、OpenAPI spec(例:AWS API Gatewayからエクスポートしたもの)があれば、
./node_modules/.bin/stepci generate {spec} {path}
を使った方が圧倒的に早い(後で気づいた。。。)。
テストケースの書き方は公式ドキュメント参照。
REST API をワンコマンドでテストする
./node_modules/.bin/stepci run workflow.yml
実行結果の例
環境(env)を変更指定することも可能
./node_modules/.bin/stepci run workflow.yml -e host=example2.com
テストケース作成のポイント
- APIレスポンスを後続のAPIテストケースで使うようにした方がテストケースのメンテが楽になる。
- 各テスト(tests配下)は並列で実行されるので、テストは極力分けたほうが早く終わる。
- データ収集を無効にするときは下記をテストケースに設定する。
env:
STEPCI_DISABLE_ANALYTICS: "1"
- APIレスポンスを加工(split+n番目を抽出)して後続のAPIのインプットとしたかったが方法が分からず。APIレスポンス設計がいけてなかったのかも。
テストケース例
Cognitoでtokenを発行し、そのtokenを付けてGET /dataをコール。レスポンスステータスが200であることを確認する。
version: "1.1"
name: Status Check
env:
STEPCI_DISABLE_ANALYTICS: "1"
apiHost: https://{apigateway-id}.execute-api.{region}.amazonaws.com/{stage}
tokenHost: https://cognito-idp.{region}.amazonaws.com/
cognitoClientId: {cognitoclient-id}
tests:
AuthUserTest:
steps:
- name: Token request
http:
url: ${{env.tokenHost}}
method: POST
headers:
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Content-Type: application/x-amz-json-1.1
json:
ClientId: ${{env.cognitoClientId}}
AuthFlow: USER_PASSWORD_AUTH
AuthParameters:
USERNAME: {cognito-user}
PASSWORD: {cognito-password}
captures:
idToken:
jsonpath: $.AuthenticationResult.IdToken
check:
status: 200
- name: GET data
http:
url: ${{env.apiHost}}/data
method: GET
auth:
bearer:
token: ${{captures.idToken}}
check:
status: 200
Discussion