[英]mocha nesting/replicating tests
給定一個滿足某些不變性的數據結構,我想在進行各種操作后測試該數據結構實例的狀態。 做這個的最好方式是什么?
describe('data-structure', function() {
var x;
beforeEach(function() {
x = getDataStructure();
});
describe('satisfies invariants', function() {
// run tests on 'fresh' x
it('should ...', function() {
// ...
});
// ...
});
describe('operation 1', function() {
it('should preserve invariants', function() {
x.doSomething();
// run 'satisfies invariants' tests on modified x
});
});
});
我曾考慮過使用afterEach
掛鈎,但我不認為x
保留在那里?
afterEach(function() {
// somehow run 'satisfies invariants' test
});
也許我可以將'satisfies invariants'
重構為一種方法,但是如果mocha可以報告每個操作哪些不變式測試失敗,那就太好了,例如
data-structure
satisfies invariants
should satisfy invariant 1 ...
...
operation 1
should satisfy invariant 1 ...
...
operation 2
should satisfy invariant 1 ...
...
使用結構
describe('data-structure', function() {
var x;
describe('satisfies invariants', function() {
afterEach(function() {
it('should satisfy invariant 1', function() {
// x.value === a again
// ...
});
// ...
});
it('should work after operation 1', function() {
x = getDataStructure(); // x.value === a
x.operation1(); // x.value === b
});
it('should work after operation 2', function() {
x = getDataStructure();
x.operation2();
});
// ...
});
});
似乎沒有保留對x
的更改。
下面是一個示例,如果我忘記了我們所討論的內容,請告訴我:
var assert = require('assert');
describe('data-structure', function() {
var x;
beforeEach(function() {
// freshly created data structure for each describe block below
x = getDataStructure;
});
describe('satisfies invariants', function() {
after(function() {
// it executes those tests only once after all the it block below
assert(x); // put your tests here
});
it('op 1.1', function() {
do_something_on(x);
});
it('op 1.2', function() {
// keep in mind that x is the same instance of the previous test
do_something_else_on(x);
});
// so on
});
describe('satisfies something else', function() {
// here you have a new instance of x, because of the outer beforeeach
after(function() {
// it executes those tests only once after all the it block within this describe block
assert(x); // put your tests here
});
it('op 2.1', function() {
do_something_on(x);
});
it('op 2.2', function() {
// keep in mind that x is the same instance of the previous test, but not the one used in 1.2
do_something_else_on(x);
});
// so on
});
// so on
});
這段代碼應該使您了解可以訪問哪些實例以及在何處。 如果缺少某些內容,請告訴我,我將去修復它。
Mocha不支持像上一片段一樣將it
放入鈎子中。 ( afterEach
是一個鈎子)。 在某些瑣碎的情況下,您可能會得到理想的行為,但這只是運氣。 一旦轉到更復雜的測試套件,您將無法獲得預期的行為。
而且,我建議afterEach
在那種測試中是錯誤的地方。 您應該僅使用鈎子來設置和拆除測試環境,而不能在代碼狀態上執行斷言。 Mocha將鈎子中的任何失敗視為“測試套件損壞,中止!”。 而不是測試失敗。 看這個例子,例如:
var assert = require('assert');
describe("test", function () {
var x;
beforeEach(function () {
x = { foo: 'something' };
});
afterEach(function () {
assert(x.foo === 'something');
});
it("one", function () {});
it("two", function () {
x.foo = 'something else';
});
it("three", function () {});
});
從理論上講,沒有理由不應該運行測試three
但是如果在運行測試two
之后的afterEach
掛鈎中發生故障,Mocha只會在此處停止運行測試。 輸出(省略最后的堆棧跟蹤)為:
test
✓ one
✓ two
1) "after each" hook
2 passing (14ms)
1 failing
注意如何將two
標記為通過,但掛鈎失敗。 請注意,甚至從未嘗試過three
。 一旦鈎子出現故障,摩卡就停在那里。
您應該只創建一個從每個測試調用的函數來測試您的不變式。 例如:
var assert = require('assert');
describe("test", function () {
var x;
beforeEach(function () {
x = { foo: 'something' };
});
function testInvariant() {
assert(x.foo === 'something');
}
it("one", function () {
testInvariant();
});
it("two", function () {
x.foo = 'something else';
testInvariant();
});
it("three", function () {
testInvariant();
});
});
如果在上面的代碼上運行Mocha,您將得到(再次,省略最終的堆棧跟蹤):
test
✓ one
1) two
✓ three
2 passing (10ms)
1 failing
two
被標記為失敗,摩卡繼續運行three
,這是成功的。
如果不想在每個測試中編寫testInvariant()
,則可以創建一個為您添加它的函數。 例如:
var assert = require('assert');
describe("test", function () {
var x;
beforeEach(function () {
x = { foo: 'something' };
});
function makeTest(name, fn) {
it(name, function () {
fn();
assert(x.foo === 'something');
});
}
makeTest("one", function () {
});
makeTest("two", function () {
x.foo = 'something else';
});
makeTest("three", function () {
});
});
這將產生與先前代碼段相同的輸出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.