我想理解为什么每个describe()
内部的所有块it()
都在describe()
之前运行。
这是一个CodeSandbox example,每个describe
和it
块中都有一个日志。
describe("sum A", () => {
window.innerWidth = 100;
console.log("describe A", window.innerWidth);
beforeAll(() => {
window.innerWidth = 105;
console.log("describe A before", window.innerWidth);
});
it("1. should add 1 and 2", () => {
console.log("it A1", window.innerWidth);
expect(1 + 2).toBe(3);
});
});
describe("sum B", () => {
console.log("describe B", window.innerWidth, "why does it run before it A1?");
beforeAll(() => {
window.innerWidth = 205;
console.log("describe B before", window.innerWidth);
});
it("1. should add 1 and 2", () => {
console.log("it B1", window.innerWidth);
expect(1 + 2).toBe(3);
});
});
您会注意到,第二个describe块中的日志在第一个describe块中的it()
之前运行。
为什么会这样?当我们需要在该describe块中共享数据并确定其范围时,是否应该避免在代码的那部分工作,而更喜欢使用beforeAll()
?
答案 0 :(得分:2)
运行Jest
时,它将查找所有测试文件并运行每个文件。
每个测试文件在Jest
提供的环境中运行,该环境包括describe
,it
,beforeAll
等全局变量。所有这些全局变量都有一个回调参数定义他们的行为。
运行测试文件时,顶层代码即会运行...包括所有顶层describe
调用。
当describe
运行registers a test suite,然后运行its callback is called immediately时。
这与the callback is recorded but not immediately called中的it
,beforeAll
,beforeEach
等不同。
这意味着所有describe
回调函数都按照在测试文件中出现的顺序被称为深度优先,如以下简单示例所示:
describe('1', () => {
console.log('1');
describe('2', () => { console.log('2'); });
describe('3', () => {
console.log('3');
describe('4', () => { console.log('4'); })
describe('5', () => { console.log('5'); })
})
describe('6', () => { console.log('6'); })
})
describe('7', () => {
console.log('7');
it('(since there has to be at least one test)', () => { });
})
...按顺序记录1
-7
。
所有describe
回调的初始运行称为collection phase,在此期间定义测试套件以及任何beforeAll
,beforeEach
,{收集了{1}},it
等。
收集阶段完成后,test
...
以在收集阶段遇到的顺序依次运行所有测试,等待每个测试完成并整理后再继续。
对于每个测试(每个在全局Jest
或it
函数中注册的回调函数)test
links together any before callbacks, the test callback itself, and any after callbacks并按顺序运行结果函数。
我们是否应该避免在代码的那部分做任何事情,而在需要共享和描述该描述块中的数据时更喜欢使用
Jest
?
对于不共享的简单内容,可以将其包含在beforeAll()
中:
describe
...但是describe('val', () => {
const val = '1';
it('should be 1', () => {
expect(val).toBe('1'); // Success!
});
});
中的代码可能导致共享数据出现问题:
describe
...可以通过使用describe('val', () => {
let val;
describe('1', () => {
val = '1';
it('should be 1', () => {
expect(val).toBe('1'); // FAIL! (val gets set to 2 in the second describe)
})
})
describe('2', () => {
val = '2';
it('should be 2', () => {
expect(val).toBe('2'); // Success!
})
})
});
调用来固定:
before
...或者只是将数据范围限定到describe('val', () => {
let val;
describe('1', () => {
beforeEach(() => {
val = '1';
});
it('should be 1', () => {
expect(val).toBe('1'); // Success!
})
})
describe('2', () => {
beforeEach(() => {
val = '2';
});
it('should be 2', () => {
expect(val).toBe('2'); // Success!
})
})
});
:
describe
在您的示例中,您使用的是describe('val', () => {
describe('1', () => {
const val = '1';
it('should be 1', () => {
expect(val).toBe('1'); // Success!
})
})
describe('2', () => {
const val = '2';
it('should be 2', () => {
expect(val).toBe('2'); // Success!
})
})
});
,它是一个共享的全局变量,因此您将要使用window.innerWidth
函数,因为它的作用域不能限于before
。
还要注意您can't return anything from a describe
,因此,如果您的测试需要任何异步设置,则需要使用describe
函数,您可以在其中将before
的{{1}}返回等待:
Promise