Mocha: skip doesn't work for nested describes

Created on 23 Jan 2017  路  10Comments  路  Source: mochajs/mocha

copied from my question on SO

I have some code below:

const assert = require('assert')

describe('server', function() {
  before(function() {
    // HACK: skip the tests in staging environment until we find to provide db in it
    if(process.env.NODE_ENV === 'staging') {
      this.skip();
    }
  });

  it('list request', function() {
    assert.fail('fails wo db')
  })
  describe('detail requests', function() {
    it('some arguments', function() {
      assert.fail('fails wo db')
    })
  })
})

When I run NODE_ENV='staging' npm test:

> @ test /Users/kharandz/Projects/mocha-bug
> mocha



  server
    - list request
    detail requests
      1) some arguments


  0 passing (10ms)
  1 pending
  1 failing

  1) server detail requests some arguments:
     AssertionError: 'fails wo db' undefined undefined
      at Context.<anonymous> (test/sample.spec.js:16:14)

But I expect that all the tests are skipped. So, the question:

  • How to achieve the expected behavior without copying before-code in every describe?
  • Is there any reason why it works like this?
question

Most helpful comment

for me worked setting pending prop to true

before(function () {
    this.test.parent.pending = true;
    this.skip();
});

-- skips current and all nested describes

All 10 comments

this is a different suite for each describe.

I think it would make more sense for you to pull your condition out of the mocha internals altogether:

if(process.env.NODE_ENV !== 'staging') {
  describe('...', function () {
    describe('...', function () {
    });
  });
}

Does that solve your problem?

Thanks for the answer. I actually do it like you propose, but technically its a hack. I want to have the output:
5 pending (or any other number).
With the current solution we are omitting the tests instead of skipping them

If I wanted to display pending tests I would probably do something like

var envDescribe = process.NODE_ENV === 'staging' ? describe.skip : describe;

envDescribe('...', function () {
  envDescribe('...', function () {
  });
});

it solves the issue, thx. If you want a few points on SO, feel free to copypaste you answer and I'll receive

I'm fine without the points. Happy testing :)

@Munter I found a problem with your solution. If somebody write something like envDescribe.skip, we will have a problem and it will appear only under some circumstances which makes it's really flaky

When that does appear, though, it should throw a hard error and block the test suite from even running (thus making the problem impossible to overlook), if I'm not mistaken?

A possible alternative may be to var envDescribe = process.NODE_ENV === 'staging' ? describe.skip : function() { return describe.apply(null, arguments) };, which, if I've written it correctly (not sure off the top of my head if null in the apply call would need to be this instead), would make envDescribe.skip(...) always be an error. If I'm also right that the error's obvious, perhaps that would do?

This definitely is surprising behaviour, given that most other behaviour is nested by context (e.g describe.skip certainly is). Worth re-opening?

Definitely worth re-opening as I'm trying to skip in an async function (and I don't think that wrapping everything in the callback is nice TBH).

for me worked setting pending prop to true

before(function () {
    this.test.parent.pending = true;
    this.skip();
});

-- skips current and all nested describes

Was this page helpful?
0 / 5 - 0 ratings