NightwatchでのAPIテスト
概要
APIテストは、アプリケーションのAPI層をテストするソフトウェアテストの一種です。
APIテストでは、クライアントアプリケーションとサーバー間のリクエストとレスポンスをテストします。これは通常、HTTPリクエストをAPIエンドポイントに送信し、返されたレスポンスを検証することで行われます。APIテストの主な目的は、APIが期待どおりに動作し、さまざまな入力シナリオに対して正しいデータとエラーを返すことを保証することです。
全体として、APIテストは、アプリケーションのAPI層の信頼性と機能を保証するソフトウェアテストの重要な側面であり、開発者が堅牢でスケーラブルなソフトウェアアプリケーションを構築できるようにします。
どのように機能するのですか?
APIテストを実行するには、公式の@nightwatch/apitestingプラグインをインストールする必要があります。このプラグインは以下の機能を提供します。
Nightwatch 2.6.4以上が必要です。
インストール
1)NPMからプラグインをインストールします
npm i @nightwatch/apitesting --save-dev
2)リストにプラグインを追加します
Nightwatch設定を更新して、リストにプラグインを追加します
module.exports = {
plugins: ['@nightwatch/apitesting']
// other Nightwatch settings...
}
3)ブラウザセッションを無効にします
また、APIテストのみを行うため、ブラウザセッションをオフにする必要があります。これは、以下に示すようにnightwatch.conf.jsにAPIテスト用の新しい環境を追加することで実現できます。
module.exports = {
// ....
api_testing: {
start_session: false,
webdriver: {
start_process: false,
}
}
}
設定
プラグインには、現在のところ、コンソールにHTTPレスポンスをログに記録するかどうかという1つの構成オプションしかありません。これは、nightwatch.json
(またはnightwatch.conf.js
)構成ファイルで構成できます。
{
"@nightwatch/apitesting" : {
"log_responses": true
}
}
APIヘッダーとレスポンスのテスト
Nightwatchは内部でsupertest
を使用しているため、さまざまなタイプのREST APIヘッダーとレスポンスをテストできます。
GETリクエスト
describe('api testing', function () {
it('get api test', async function({supertest}) {
await supertest
.request("https://petstore.swagger.io/v2")
.get("/pet/findByStatus?status=available")
.expect(200)
.expect('Content-Type', /json/)
.then(function(response){
expect(response._body.length).to.be.greaterThan(0);
});
});
});
POSTリクエスト
describe('api testing', function () {
it('post api test', async function({supertest}) {
await supertest
.request("https://petstore.swagger.io/v2")
.post("/pet")
.send({
"id": 0,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
})
.expect(200)
.expect('Content-Type', /json/)
.then(function(response){
expect(response._body.name).to.be.equal("doggie");
});
});
});
APIテストの実行
APIテストが、start_session
とwebdriver -> start_process
がfalse
に設定されているenvironment
に対して実行されていることを確認してください。
npx nightwatch <path to tests> --env api_testing
HTMLレポート
テストが実行されると、結果はHTMLレポートで確認できます。
統合モックサーバー
@nightwatch/apitesting
プラグインは、expressに基づく組み込みのモックサーバーも提供しており、受信HTTPリクエストをアサートするために使用できます。
モックサーバーのサンプルを次に示します
describe('api testing with supertest in nightwatch POST', function () {
let server;
before(async function(client) {
server = await client.mockserver.create();
server.setup((app) => {
app.post('/api/v1/datasets/', function (req, res) {
res.status(200).json({
id: 'test-dataset-id'
});
});
});
await server.start(3000);
});
after(() => {
server.close();
});
it('demo test', async function(client) {
const req = await server.request()
.post('/api/v1/datasets/')
.send({name: 'medea'})
.set('Accept', 'application/json')
.expect(200)
.expect('Content-Type', /json/);
await client.assert.deepStrictEqual(server.route.post('/api/v1/datasets/').requestBody, {name: 'medea'});
});
});
モックサーバーAPI
const mockServer = await client.mockserver.create()
– 新しいモックサーバーインスタンスを作成しますawait mockServer.setup(definition)
– 提供されたルート定義で既存のモックサーバーインスタンスを設定します 例await mockServer.setup((app) => { app.get('/api/v1/schemas', function (req, res) { console.log('GET /api/v1/schemas called');
res.status(200).json([ { id: 'test-schema-id1' }, { id: 'test-schema-id2' } ]); }) });await mockServer.start(port)
– 指定されたポートで既存のモックサーバーインスタンスを開始しますawait mockServer.route(path)
– 指定されたルート上のsinonスパイを返します
受信リクエストのアサート
mockServer.route(path)
メソッドを使用して、指定されたルートのスパイを取得します。次に、sinonアサーションを使用して、受信リクエストをアサートできます。
例
前のモックサーバーのセットアップ例を考えてみましょう。GET /api/v1/schemas
ルートが呼び出されたことをアサートしたい場合は、次のように実行できます
it('demo test', async function(client) {
client
.assert.strictEqual(mockServer.route.get('/api/v1/schemas').calledOnce, true, 'called once')
.assert.strictEqual(mockServer.route.get('/api/v1/schemas').calledTwice, false);
});
リクエストヘッダーのアサート
また、たとえば、chaiを使用する組み込みのexpect()
アサーションAPIを使用して、リクエストヘッダーをアサートすることもできます
it('demo test', async function(client) {
const {requestHeaders} = mockServer.route.get('/api/v1/schemas');
client.expect(requestHeaders).to.have.property('connection', 'close');
});
受信POSTデータのアサート
また、受信POSTデータをアサートすることもできます
- まず、モックサーバーのPOSTルートを設定します
await mockServer.setup((app) => {
app.post('/api/v1/datasets/', function (req, res) {
res.status(200).json({
id: 'test-dataset-id'
});
});
});
- 次に、
mockServer.route.post(path)
メソッドを使用して、指定されたルートのスパイを取得します。次に、sinonアサーションを使用して、受信リクエストをアサートできます。
it('demo test', async function(client) {
const {requestBody} = mockServer.route.post('/api/v1/schemas');
await client.assert.deepStrictEqual(requestBody, {name: 'medea'});
});
受信リクエストテストを待機するには、waitUntil()
コマンドを使用できます。
waitUntil
を使用した例
it('demo test', async function(client) {
const timeoutMs = 15000;
const retryIntervalMs = 500;
await client.waitUntil(async function () {
const spy = server.route.get('/api/v1/schemas');
if (spy) {
return spy.calledOnce;
}
return false;
}, timeoutMs, retryIntervalMs, new Error(`time out reached (10000ms) while waiting for API call.`));
});