Codeceptionがもう色々と辛くなってきたのでNodeに変更。
APIのシナリオ検証を行いたかったので、supertestとasyncを使って進めていきます。
考慮したポイント
- セッションに対応させる
- 同期的なAPIのシナリオ発行を綺麗に書けるようにする。
インストール
$ npm install supertest async should --save
$ npm install mocha -g
適当にtest
ディレクトリ作成してtest.jsとかに以下を記述。
var request = require('supertest');
var async = require("async");
var debugApi = function(argent){
return agent
.get('/debug')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200)
.expect(function(res){
res.body.debug.should.equal("this is debug route")
res.body.should.have.property("time")
})
}
describe('GET /user', function() {
this.timeout(10000)
it('respond with json', function (done) {
var agent = request.agent("http://localhost:9000")
async.series([
// 最初のAPI送信
function(cb){
debugApi(agent)
.expect(function (res) {
res.body.session.should.equal(0)
}).end(cb)
},
// 2本目のAPI送信
function(cb){
debugApi(agent)
.expect(function (res) {
res.body.session.should.equal(1)
}).end(cb)
}
],done);
});
});
以下でテスト実行
$ mocha --require should
supertest の解説
supertestではクライアントを作成して、APIを投げていく。
クライアントは request(url)
やrequest.argent(url)
でオブジェクトとして取得できるが、後者はセッション等が保存される点が異なる。
検証用のAPI expect
にはいくつかのパターンがあり、
-
expect(int[,cb])
: ステータスコードの検証 -
expect(int,obj[,cb])
: ステータスコードとBODYの検証 -
expect(obj[,cb])
: BODYの検証 -
expect(fn[,cb])
: クロージャによる検証
の4つがある。Bodyの検証に関しては完全一致or文字列の正規表現なので、
APIの検証時にはクロージャを使っていくのが楽そう。
.expect(function (res) {
res.body.should.have.property("message")
res.body.session.should.equal(1)
}).end(cb)
callback内でのshould
の利用は実行時に--require should
をつけると有効になる。
雑感
Codeception よりも比較的楽に書けそうな気がする。
でもやっぱりfunction書きまくるの辛いので、この手のコードはCoffeescriptとかで雑に書きたい。そのためだけにcoffeescript入れるのもなぁ…
async の導入でコードの読みやすさ大分変わりました。
実コードではAPIを利用した会員登録 → ログイン → ログアウト → 再ログイン → ユーザ情報変更 → ユーザ情報削除 と言った具合のシナリオ検証を進めていくことになるので、コールバック地獄で死にます。
デバッグの表示が若干不親切なのがつらい。
codecept run --debug
的な感じのアレば良いなぁ…と思ったのですがどうなんでしょうか。
複数ファイルになってきた時にmochaテストのグループ化とかそういうのどうしようかで若干悩んではいる。ベスト・プラクティスが聞きたい。
しゃあないとは思いつつ、describe->it->async->expect で四階層降りるのが辛い。