しばらく書いてなかったけどメモ程度に
dreddとは
dreddはopenapi(swagger)やAPI Blueprintの定義を読み込んでテストを実行してくれる便利なツールです。
例えば localhost:8080
でAPIサーバを動かして
dredd openapi/schema.yaml http://localhost:8080/v1/
のようにすればschema.yamlに定義されたAPIの定義に従ってリクエストを送り、レスポンスが仕様に従っているかテストしてくれます。
が、ログインしてtokenを貰ってそのtokenでアクセスするというようなAPIはそのままではテストできません。
hooksという仕組みを使うと、レスポンスからtokenを取得して以後はそれを使う、といった動作が可能になります。
dredd hooks
ドキュメントにある通り、hooksは様々な言語で書くことができますが、とりあえずdreddと同じnode.jsでやってみます。
(なぜかと言うと、dockerのコンテナ一つで完結させたい場合に処理系を複数入れるのが面倒だから)
schema
例えばこんなschemaがあるとします。(端折っているのでこのままでは動きません)
openapi: 3.0.2
info:
title: login api sample
version: 1.0.0
servers:
- url: http://localhost:8080/v1
description: development env
paths:
/sign_in:
post:
description: Sign In
operationId: signIn
requestBody:
required: true
content:
application/json; charset=utf-8:
schema:
$ref: '#/components/schemas/AuthRequest'
example:
email: "foo@bar.jp"
password: "password"
responses:
'200':
description: successfully authorized
content:
application/json; charset=utf-8:
schema:
$ref: '#/components/schemas/Auth'
components:
schemas:
Auth:
type: object
description: authorized response
properties:
token:
type: string
example: "abcdefgh12345678"
AuthRequest:
type: object
properties:
email:
type: string
password:
type: string
required:
- email
- password
hooks
hooksは任意のディレクトリに置けますが、 test/hooks/sign_in.js
に置くものとします。
var hooks = require('hooks');
var stash = {};
// hook to retrieve session on a login
hooks.after('/sign_in > POST > 200 > application/json; charset=utf-8', function (transaction) {
stash['token'] = JSON.parse(transaction.real.body)['token'];
});
// hook to set the session cookie in all following requests
hooks.beforeEach(function (transaction) {
if(stash['token'] != undefined){
if (transaction.expected.statusCode != "401"){
transaction.request.headers['Authorization'] = "Bearer " + stash['token'];
};
};
});
実行
dredd openapi/schema.yaml http://localhost:8080/v1/ --hookfiles="test/hooks/*.js"
すると最初に /sign_in
にアクセスした時のレスポンスから token
を保存し、以降はAuthorizationヘッダに埋め込んでくれます。
ただし 401
のテストの場合は除外するようにしています。
注意点
- テストはschemaの順番に実行されるので、先頭に
/sign_in
を書いておかないとそれより前のテストは失敗します。 - APIの実装によりますが、 ログアウト時にtokenを無効化するようなAPIの場合、ログアウトは最後に書かないと途中でtokenが無効化して以後は失敗します。
その他、hooksを上手く使うと404などの異常系もテストできて便利です。
おわりに
swaggerもdreddも最近使い始めたばかりなので、間違い等ありましたらご指摘ください。
他にもTIPSありましたら教えてくれると嬉しいです。