在每个套件之前而不是在每个测试之前运行Mocha设置

时间:2022-04-24 19:20:41

Using NodeJS and Mocha for testing. I think I understand how before() and beforeEach() work. Problem is, I'd like to add a setup script that runs before each "describe" rather than before each "it".

使用NodeJS和Mocha进行测试。我想我理解()之前和之前的工作。问题是,我想添加一个安装脚本,在每个“description”之前运行,而不是在每个“it”之前。

If I use before() it will run only once for the entire suite, and if I use beforeEach() it will execute before every single test, so I'm trying to find a middle ground.

如果我使用before(),它将在整个套件中只运行一次,如果我使用beforeEach(),它将在每个测试之前执行,因此我试图找到一个中间地带。

So, if this is my test file:

如果这是我的测试文件

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){
    ...
  });
});

I'd like to have "setupStuff" contain a function that runs before 'Suite one' and 'Suite two'

我想要"setupStuff"包含一个函数在" Suite 1 "和" Suite 2 "之前运行

Or, in other words, before 'S1 Test one' and 'S2 Test one' but NOT before 'S1 Test two'.

或者,换句话说,在S1测试1和S2测试1之前,而不是在S1测试2之前。

Can it be done?

可以做到吗?

3 个解决方案

#1


16  

There's no call similar to beforeEach or before that does what you want. But it is not needed because you can do it this way:

没有类似于before - each或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


6  

you can also do it in this more flexible way:

你也可以用更灵活的方式来做:

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


0  

I have found this approach worked for me, it patches all describe suites.

我发现这种方法对我很有效,它的补丁都描述了套件。

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;

Differences from the other answers are:

与其他答案的不同之处在于:

  • The use of bind to call the tests which ensures that if they call functions on this, such as this.timeout(1000) will still work.
  • 使用bind来调用测试,以确保如果他们调用这个函数,比如this.timeout(1000)仍然有效。
  • Handling .skip and .only means that you can still use those on your suite, eg describe.skip to temporarily suppress suites.
  • 处理。skip和。only意味着你仍然可以在你的套件中使用它们,如describe。跳转到临时抑制套件。
  • Replacing the describe function by name allows for a less intrusive injection.
    • This may not be to everyone's taste, in which case obviously an alternative function name can be used whilst still making use of the correct handling of calling the tests and only and skip.
    • 这可能不是每个人都喜欢的,在这种情况下,显然可以使用一个替代函数名,同时仍然使用调用测试的正确处理,并且只调用和跳过。
  • 用名称替换description函数可以减少插入性。这可能不是每个人都喜欢的,在这种情况下,显然可以使用一个替代函数名,同时仍然使用调用测试的正确处理,并且只调用和跳过。

#1


16  

There's no call similar to beforeEach or before that does what you want. But it is not needed because you can do it this way:

没有类似于before - each或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


6  

you can also do it in this more flexible way:

你也可以用更灵活的方式来做:

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


0  

I have found this approach worked for me, it patches all describe suites.

我发现这种方法对我很有效,它的补丁都描述了套件。

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;

Differences from the other answers are:

与其他答案的不同之处在于:

  • The use of bind to call the tests which ensures that if they call functions on this, such as this.timeout(1000) will still work.
  • 使用bind来调用测试,以确保如果他们调用这个函数,比如this.timeout(1000)仍然有效。
  • Handling .skip and .only means that you can still use those on your suite, eg describe.skip to temporarily suppress suites.
  • 处理。skip和。only意味着你仍然可以在你的套件中使用它们,如describe。跳转到临时抑制套件。
  • Replacing the describe function by name allows for a less intrusive injection.
    • This may not be to everyone's taste, in which case obviously an alternative function name can be used whilst still making use of the correct handling of calling the tests and only and skip.
    • 这可能不是每个人都喜欢的,在这种情况下,显然可以使用一个替代函数名,同时仍然使用调用测试的正确处理,并且只调用和跳过。
  • 用名称替换description函数可以减少插入性。这可能不是每个人都喜欢的,在这种情况下,显然可以使用一个替代函数名,同时仍然使用调用测试的正确处理,并且只调用和跳过。