给定满足某些不变量的数据结构,我想在各种操作之后测试数据结构实例的状态。这样做的最佳方式是什么?
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
。
答案 0 :(得分:0)
以下是一个例子,如果我忘记了我们讨论的内容,请告诉我:
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
});
这段代码可以让您了解哪些实例可以访问以及在哪里。 如果它缺少某些东西,请告诉我,我会去解决它。
答案 1 :(得分:0)
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
,但是当测试afterEach
运行后two
挂钩发生故障时,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
被标记为失败,Mocha继续运行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 () {
});
});
这将产生与前一代码片段相同的输出。