MochaとChaiでなんでもテスト の2本目 基本編 の続きです。

今回は、テストを自動化する上で色々便利な mocha の機能の使い方です。

[ Windows 10 / Node.js 10.15.3 / mocha@6.1.4 ]

  1. before / after
  2. only / skip
  3. timeout
  4. ESLintでエラーが出る場合は?

before / after

初期データ投入やゴミ掃除に便利な before()/after()beforeEach()/afterEach() の使い方です。

その名の通り、テストの前後に行う処理を設定できる機能です。describe() の外側と内側のどちらに書くかによって、適用される範囲が変わります。

  • describe() の外側で before()/after() ... テストプログラムの最初/最後に1回だけ起動
  • describe() の外側で beforeEach()/afterEach() ... 全ての it() の前/後に1回ずつ起動
  • describe() の内側で before()/after() ... describe() の最初/最後に1回だけ起動
  • describe() の内側で beforeEach()/afterEach() ... describe() 内の全ての it() の前/後に1回ずつ起動

全ての describe() の前後に起動されるものは無いようです。外側で beforeEach() しても、適用されるのは全ての it() の前後となります。

ちなみに it() の内側で書いた場合は、describe() の外側で書いた場合と同じ動きになります。当該の it() 内だけで効いてくれたりはしません。

動作サンプル
'use strict';

before(function() {
	console.log('[before] 最初に一回だけ');
});
beforeEach(function() {
	console.log('[beforeEach] 全てのitの前に一回ずつ');
});

after(function() {
	console.log('[after] 最後に一回だけ');
});
afterEach(function() {
	console.log('[afterEach] 全てのitの後に一回ずつ');
});

describe('てすと 1', function() {
	before(function() {
		console.log('[before-1] このdescribeの最初に一回だけ');
	});
	beforeEach(function() {
		console.log('[beforeEach-1] このdescribeの全てのitの前に一回ずつ');
	});
	
	after(function() {
		console.log('[after-1] このdescribeの最後に一回だけ');
	});
	afterEach(function() {
		console.log('[afterEach-1] このdescribeの全てのitの後に一回ずつ');
	});

	it('けーす 1-1', function() {});
	it('けーす 1-2', function() {});
});

describe('てすと 2', function() {
	it('けーす 2-1', function() {});
	it('けーす 2-2', function() {});
});
実行結果
[before] 最初に一回だけ
  てすと 1
[before-1] このdescribeの最初に一回だけ
[beforeEach] 全てのitの前に一回ずつ
[beforeEach-1] このdescribeの全てのitの前に一回ずつ
    √ けーす 1-1
[afterEach-1] このdescribeの全てのitの後に一回ずつ
[afterEach] 全てのitの後に一回ずつ
[beforeEach] 全てのitの前に一回ずつ
[beforeEach-1] このdescribeの全てのitの前に一回ずつ
    √ けーす 1-2
[afterEach-1] このdescribeの全てのitの後に一回ずつ
[afterEach] 全てのitの後に一回ずつ
[after-1] このdescribeの最後に一回だけ

  てすと 2
[beforeEach] 全てのitの前に一回ずつ
    √ けーす 2-1
[afterEach] 全てのitの後に一回ずつ
[beforeEach] 全てのitの前に一回ずつ
    √ けーす 2-2
[afterEach] 全てのitの後に一回ずつ

[after] 最後に一回だけ

  4 passing (31ms)

only / skip

一部分だけの再テスト等に便利な only()/skip() の使い方です。

only()/skip() は、describe または it にチェーンして使うことができます。

only() をチェーンすると、実行時に当該 describe (または it) のみがテストされます。テストプログラムの開発中に、同じケースだけを繰り返し起動したりする時に便利です。

skip() をチェーンすると、実行時に当該 describe (または it) がスキップされます。変なエラーケースとか、普段は通らないケースを一つのテストプログラムに書いておきたい時に使えます。

1-1, 1-2 だけ実行
describe.only('てすと 1', function() {
	it('けーす 1-1', function() {});
	it('けーす 1-2', function() {});
});
describe('てすと 2', function() {
	it('けーす 2-1', function() {});
	it('けーす 2-2', function() {});
});
2-1, 2-2 だけ実行
describe.skip('てすと 1', function() {
	it('けーす 1-1', function() {});
	it('けーす 1-2', function() {});
});
describe('てすと 2', function() {
	it('けーす 2-1', function() {});
	it('けーす 2-2', function() {});
});
1-1, 1-2, 2-2 だけ実行
describe('てすと 1', function() {
	it('けーす 1-1', function() {});
	it('けーす 1-2', function() {});
});
describe('てすと 2', function() {
	it.skip('けーす 2-1', function() {});
	it('けーす 2-2', function() {});
});
1-2 だけ実行
describe.only('てすと 1', function() {
	it.skip('けーす 1-1', function() {});
	it('けーす 1-2', function() {});
});
describe('てすと 2', function() {
	it('けーす 2-1', function() {});
	it('けーす 2-2', function() {});
});
1-2 だけ実行
describe.only('てすと 1', function() {
	it('けーす 1-1', function() {});
	it('けーす 1-2', function() {});
});
describe('てすと 2', function() {
	it.only('けーす 2-1', function() {});
	it('けーす 2-2', function() {});
});
1-1, 1-2, 2-1 だけ実行
describe.only('てすと 1', function() {
	it('けーす 1-1', function() {});
	it('けーす 1-2', function() {});
});
describe('てすと 2', function() {
	it.only('けーす 2-1', function() {});
	it('けーす 2-2', function() {});
});

timeout

リモートのリソースにアクセスする場合など、ちょっと時間がかかるかもしれないケースでは、Mochaがタイムアウトしてエラーとなる場合があります。

Mochaのタイムアウトは、デフォルトでは it() ごとに2,000ミリ秒です。なお、上述の before()beforeEach() にも同様のタイムアウトがあります。

it内でタイムアウト
  1) てすと
       けーす 1:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (C:\path\to\mytest\script.js)
before内でタイムアウト
  1) "before all" hook in "{root}":
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

このタイムアウトを変更するには、describe() it() before() 等の内側で this.timaout(ミリ秒) します。describe() 内で行った場合、describe() 内の全ての it() に適用されます。

'use strict';

before(function() {
	this.timeout(5000);
	// ここはタイムアウト5000ミリ秒
});

describe('てすと', function() {
	this.timeout(4000);
	it('けーす1', function() {
		// このケースはタイムアウト4000ミリ秒
	});
	it('けーす2', function() {
		this.timeout(3000);
		// このケースはタイムアウト3000ミリ秒
	});
});

ESLintでエラーが出る場合は?

ESLintを入れてる環境では、テストプログラム内で describe とかが未定義 (not defined) でエラーになってしまいます。

これは、テストプログラムの先頭に以下の行を追記することで回避できます。

/* eslint-env mocha */

以上

これでたぶん基本編は終わりです。何かもっとあったら追記します。

次回はWebAPI編で、WebAPIのレスポンスをテストします。