Запуск установки Mocha перед каждым пакетом, а не перед каждым тестированием
Использование NodeJS и Mocha для тестирования. Кажется, я понимаю, как работают before() и beforeEach(). Проблема в том, что я хотел бы добавить setup script, который запускается перед каждым "описать", а не перед каждым "им".
Если я использую before()
, он будет запускаться только один раз для всего пакета, и если я использую beforeEach()
, он будет выполняться перед каждым отдельным тестом, поэтому я пытаюсь найти промежуточную точку.
Итак, если это мой тестовый файл:
require('./setupStuff');
describe('Suite one', function(){
it('S1 Test one', function(done){
...
});
it('S1 Test two', function(done){
...
});
});
describe('Suite two', function(){
it('S2 Test one', function(done){
...
});
});
Я хотел бы, чтобы "setupStuff" содержал функцию, которая работает до "Suite one" и "Suite two"
Или, другими словами, перед "S1 Test one" и "S2 Test one", но НЕ перед "S1 Test two".
Можно ли это сделать?
Ответы
Ответ 1
Нет вызова, подобного beforeEach
или before
, который делает то, что вы хотите. Но это не нужно, потому что вы можете сделать это следующим образом:
function makeSuite(name, tests) {
describe(name, function () {
before(function () {
console.log("shared before");
});
tests();
after(function () {
console.log("shared after");
});
});
}
makeSuite('Suite one', function(){
it('S1 Test one', function(done){
done();
});
it('S1 Test two', function(done){
done();
});
});
makeSuite('Suite two', function(){
it('S2 Test one', function(done){
done();
});
});
Ответ 2
вы также можете сделать это более гибким способом:
require('./setupStuff');
describe('Suite one', function(){
loadBeforeAndAfter(); //<-- added
it('S1 Test one', function(done){
...
});
it('S1 Test two', function(done){
...
});
});
describe('Suite two', function(){
loadBeforeAndAfter();//<-- added
it('S2 Test one', function(done){
...
});
});
describe('Suite three', function(){
//use some other loader here, before/after, or nothing
it('S3 Test one', function(done){
...
});
});
function loadBeforeAndAfter() {
before(function () {
console.log("shared before");
});
after(function () {
console.log("shared after");
});
}
Ответ 3
Я нашел, что этот подход работал у меня, он исправляет все описания наборов.
function suitePatches()
{
before(function()
{
// before suite behaviour
});
after(function()
{
// after suite behaviour
});
}
let origDescribe = describe;
describe = function(n,tests)
{
origDescribe(n,function()
{
suitePatches();
tests.bind(this)();
});
}
let origOnly = origDescribe.only;
describe.only = function(n,tests)
{
origOnly(n,function()
{
suitePatches();
tests.bind(this)();
});
}
describe.skip = origDescribe.skip;
Отличия от других ответов:
- Использование
bind
для вызова tests
, которое гарантирует, что если они вызовут функции на this
, такие как this.timeout(1000)
, все равно будут работать.
- Обработка
.skip
и .only
означает, что вы все равно можете использовать их в своем пакете, например describe.skip
, чтобы временно отключить пакеты.
- Замена функции
describe
по имени позволяет использовать менее интрузивные инъекции.
- Это может быть не каждый вкус, и в этом случае, очевидно, можно использовать альтернативное имя функции, но при этом использовать правильную обработку вызовов
tests
и only
и skip
.
Ответ 4
@ya_dimon решения работает, но если вы хотите, чтобы обернуть callback
функции it
, и передать параметр к нему как следует.
function dynamicTestCase(a) {
return function(done){ console.log(a); } // a is undefined
}
describe("test", function(){
before(function(){
a = 8;
});
it('POST /verifications receiveCode', dynamicTestCase(a)); // a is undefined
})
Почему определяется? a
Потому it
это выполняется раньше, before
в describe
. В этом случае решение @ya_dimon не может работать, но вы можете сделать это хитро, как показано ниже.
function dynamicTestCase(a) {
return function(done){ console.log(a()); } // a is delayed pass! a = 8, remember change a to a()
}
describe("test", function(){
before(function(){
a = 8;
});
it('POST /verifications receiveCode', dynamicTestCase(() => a)); // a is delayed pass!
})
Надеюсь, что это поможет выяснить последовательность выполнения.