Chai HTTP

Chaiアサーションを使用したHTTP統合テスト。
機能
- 統合テストのリクエスト構成
- httpアプリまたは外部サービスのテスト
- 一般的なhttpタスクのアサーション
- chai
expect
およびshould
インターフェース
インストール
これはChaiアサーションライブラリのアドオンプラグインです。npm経由でインストールしてください。
npm install chai-http
プラグイン
他のすべてのChaiプラグインと同様にこのプラグインを使用します。
var chai = require('chai')
, chaiHttp = require('chai-http');
chai.use(chaiHttp);
WebページでChai HTTPを使用するには、dist/chai-http.js
ファイルを含めるだけです
<script src="chai.js"></script>
<script src="chai-http.js"></script>
<script>
chai.use(chaiHttp);
</script>
統合テスト
Chai HTTPは、superagentを介してライブ統合テスト用のインターフェースを提供します。これを行うには、最初にアプリケーションまたはURLへのリクエストを構築する必要があります。
構築すると、呼び出したいhttp VERBリクエスト(get、postなど)を指定できるチェーン可能なAPIが提供されます。
アプリケーション/サーバー
関数(expressまたはconnectアプリなど)またはnode.js http(s)サーバーをリクエストの基礎として使用できます。サーバーが実行されていない場合、chai-httpは特定のテストでリッスンするのに適切なポートを見つけます。
注:この機能は、Webブラウザーではなく、Node.jsでのみサポートされています。
chai.request(app)
.get('/')
app
をrequest
に渡すと、着信リクエストのためにサーバーが自動的に開かれ(listen()
を呼び出すことにより)、リクエストが行われると、サーバーは自動的にシャットダウンされます(.close()
を呼び出すことにより)。複数のリクエストを作成する場合など、サーバーを開いたままにする場合は、.request()
の後に.keepOpen()
を呼び出して、サーバーを手動で閉じる必要があります
var requester = chai.request(app).keepOpen()
Promise.all([
requester.get('/a'),
requester.get('/b'),
])
.then(responses => ....)
.then(() => requester.close())
URL
リクエストの基礎としてベースURLを使用することもできます。
chai.request('https://:8080')
.get('/')
リクエストの設定
指定されたVERB(get、postなど)でリクエストが作成されたら、これらの追加メソッドを連鎖させてリクエストを作成します
メソッド | 目的 |
---|---|
.set(key, value) |
リクエストヘッダーを設定します |
.send(data) |
リクエストデータを設定します(デフォルトのタイプはJSONです) |
.type(dataType) |
.send() メソッドから送信されるデータのタイプを変更します(xml、フォームなど) |
.attach(field, file, attachment) |
ファイルを添付します |
.auth(username, password) |
Basic認証用の認証ヘッダーを追加します |
.query(parmasObject) |
いくつかのGETパラメーターを連鎖させます |
例
.set()
// Set a request header
chai.request(app)
.put('/user/me')
.set('Content-Type', 'application/json')
.send({ password: '123', confirmPassword: '123' })
.send()
// Send some JSON
chai.request(app)
.put('/user/me')
.send({ password: '123', confirmPassword: '123' })
.type()
// Send some Form Data
chai.request(app)
.post('/user/me')
.type('form')
.send({
'_method': 'put',
'password': '123',
'confirmPassword': '123'
})
.attach()
// Attach a file
chai.request(app)
.post('/user/avatar')
.attach('imageField', fs.readFileSync('avatar.png'), 'avatar.png')
.auth()
// Authenticate with Basic authentication
chai.request(app)
.get('/protected')
.auth('user', 'pass')
.query()
// Chain some GET query parameters
chai.request(app)
.get('/search')
.query({name: 'foo', limit: 10}) // /search?name=foo&limit=10
レスポンスの処理 - 従来の方法
次の例では、ChaiのExpectアサーションライブラリを使用します
var expect = chai.expect;
リクエストを作成してそのレスポンスをアサートするには、end
メソッドを使用できます
chai.request(app)
.put('/user/me')
.send({ password: '123', confirmPassword: '123' })
.end(function (err, res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
});
注意点
end
関数にはコールバックが渡されるため、アサーションは非同期的に実行されます。したがって、コールバックが完了したことをテストフレームワークに通知するメカニズムを使用する必要があります。そうしないと、アサーションがチェックされる前にテストが合格します。
たとえば、Mochaテストフレームワークでは、これはdone
コールバックを使用して実行されます。これは、コールバックが完了したことを示すものであり、アサーションを検証できます
it('fails, as expected', function(done) { // <= Pass in done callback
chai.request('https://:8080')
.get('/')
.end(function(err, res) {
expect(res).to.have.status(123);
done(); // <= Call done to signal callback end
});
});
it('succeeds silently!', function() { // <= No done callback
chai.request('https://:8080')
.get('/')
.end(function(err, res) {
expect(res).to.have.status(123); // <= Test completes before this runs
});
});
done
が渡されると、Mochaはdone()
の呼び出しまで、またはタイムアウトが切れるまで待機します。done
は完了を通知するときにエラーパラメーターも受け入れます。
レスポンスの処理 - Promise
Promise
が利用可能な場合、request()
はPromise対応ライブラリになり、then
のチェーンが可能になります
chai.request(app)
.put('/user/me')
.send({ password: '123', confirmPassword: '123' })
.then(function (res) {
expect(res).to.have.status(200);
})
.catch(function (err) {
throw err;
});
注:Node.jsバージョン0.10.xおよび一部の古いWebブラウザーには、ネイティブのPromiseサポートがありません。次のような仕様に準拠したライブラリを使用できます。
- kriskowal/q
- stefanpenner/es6-promise
- petkaantonov/bluebird
- then/promise chai-httpでrequireする前に、使用するライブラリを
global.Promise
に設定する必要があります。例:
// Add promise support if this does not exist natively.
if (!global.Promise) {
global.Promise = require('q');
}
var chai = require('chai');
chai.use(require('chai-http'));
各リクエストでCookieを保持する
場合によっては、あるリクエストからCookieを保持し、次のリクエストでそれらを送信する必要があります(たとえば、最初のリクエストでログインし、後で認証が必要なリソースにアクセスする場合)。このために、.request.agent()
が利用可能です
// Log in
var agent = chai.request.agent(app)
agent
.post('/session')
.send({ username: 'me', password: '123' })
.then(function (res) {
expect(res).to.have.cookie('sessionid');
// The `agent` now has the sessionid cookie saved, and will send it
// back to the server in the next request:
return agent.get('/user/me')
.then(function (res) {
expect(res).to.have.status(200);
});
});
注:chai.request.agent(app)
によって起動されたサーバーは、テストの完了後に自動的に閉じません。プログラムが確実に終了するように、テスト後にagent.close()
を呼び出す必要があります。
アサーション
Chai HTTPモジュールは、expect
およびshould
インターフェースに対して多数のアサーションを提供します。
.status (code)
- @param {Number} ステータス番号
レスポンスが指定されたステータスを持っていることをアサートします。
expect(res).to.have.status(200);
.header (key[, value])
- @param {String} ヘッダーキー(大文字と小文字を区別しない)
-
@param _{String RegExp}_ ヘッダー値(オプション)
Response
またはRequest
オブジェクトがヘッダーを持っていることをアサートします。値が指定されている場合、値との等価性がアサートされます。チェックするために正規表現を渡すこともできます。
注:Webブラウザーで実行する場合、同一オリジンポリシーにより、Chai HTTPは特定のヘッダーのみを読み取ることができ、アサーションが失敗する可能性があります。
expect(req).to.have.header('x-api-key');
expect(req).to.have.header('content-type', 'text/plain');
expect(req).to.have.header('content-type', /^text/);
.headers
Response
またはRequest
オブジェクトにヘッダーがあることをアサートします。
注:Webブラウザーで実行する場合、同一オリジンポリシーにより、Chai HTTPは特定のヘッダーのみを読み取ることができ、アサーションが失敗する可能性があります。
expect(req).to.have.headers;
.ip
文字列が有効なIPアドレスを表すことをアサートします。
expect('127.0.0.1').to.be.an.ip;
expect('2001:0db8:85a3:0000:0000:8a2e:0370:7334').to.be.an.ip;
.json / .text / .html
Response
またはRequest
オブジェクトに指定されたcontent-typeがあることをアサートします。
expect(req).to.be.json;
expect(req).to.be.html;
expect(req).to.be.text;
.charset
Response
またはRequest
オブジェクトに指定されたcharsetがあることをアサートします。
expect(req).to.have.charset('utf-8');
.redirect
Response
オブジェクトにリダイレクトステータスコードがあることをアサートします。
expect(res).to.redirect;
expect(res).to.not.redirect;
.redirectTo
-
@param _{String RegExp}_ ロケーションURL
Response
オブジェクトが指定されたロケーションにリダイレクトすることをアサートします。
expect(res).to.redirectTo('http://example.com');
expect(res).to.redirectTo(/^\/search\/results\?orderBy=desc$/);
.param
- @param {String} パラメーター名
- @param {String} パラメーター値
Request
オブジェクトに、指定されたキーを持ち、(オプションで)値と等しいクエリ文字列パラメーターがあることをアサートします
expect(req).to.have.param('orderby');
expect(req).to.have.param('orderby', 'date');
expect(req).to.not.have.param('limit');
.cookie
- @param {String} パラメーター名
- @param {String} パラメーター値
Request
またはResponse
オブジェクトに、指定されたキーを持ち、(オプションで)値と等しいcookieヘッダーがあることをアサートします
expect(req).to.have.cookie('session_id');
expect(req).to.have.cookie('session_id', '1234');
expect(req).to.not.have.cookie('PHPSESSID');
expect(res).to.have.cookie('session_id');
expect(res).to.have.cookie('session_id', '1234');
expect(res).to.not.have.cookie('PHPSESSID');
リリース
chai-http
は、semantic-release
を使用して、次のプラグインでリリースされます
- コミットメッセージから次のバージョンを決定する
commit-analyzer
。 release-notes-generator
でリリースを要約します- CHANGELOG.mdファイルを更新する
changelog
。 github
でGitHubリリースを公開します。git
を使用してリリースアセットをコミットします。npm
を使用して npm に公開します。
ライセンス
(MITライセンス)
Copyright (c) Jake Luer jake@alogicalparadox.com
このソフトウェアおよび関連ドキュメントファイル(「ソフトウェア」)のコピーを入手するすべての人に対し、以下の条件に従うことを条件として、ソフトウェアの使用、コピー、変更、結合、公開、配布、サブライセンス、および/またはソフトウェアのコピーの販売を含むがこれらに限定されない、ソフトウェアを制限なく扱う権利を無償でここに許可します。
上記の著作権表示およびこの許可表示は、ソフトウェアのすべてのコピーまたは実質的な部分に含まれるものとします。
本ソフトウェアは、「現状のまま」、明示的または黙示的を問わず、商品性、特定目的への適合性、および非侵害の保証を含むがこれらに限定されない、いかなる種類の保証もなしに提供されます。いかなる場合も、著者または著作権者は、契約、不法行為、またはその他によるかにかかわらず、ソフトウェアの使用またはその他の取引から、またはそれに関連して発生するいかなる請求、損害、またはその他の責任についても責任を負いません。