Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/2819 - Fix / Clarify this.skip behavior in before hooks #3225

Merged
merged 6 commits into from
Dec 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,30 @@ before(function() {
});
```

This will skip all `it`, `beforeEach/afterEach`, and `describe` blocks within the suite. `before/after` hooks are skipped unless they are defined at the same level as the hook containing `this.skip()`.

```js
describe('outer', function () {
before(function () {
this.skip();
});

after(function () {
// will be executed
});

describe('inner', function () {
before(function () {
// will be skipped
});

after(function () {
// will be skipped
});
});
});
```

> Before Mocha v3.0.0, `this.skip()` was not supported in asynchronous tests and hooks.

## Retry Tests
Expand Down
3 changes: 3 additions & 0 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ Runner.prototype.hook = function(name, fn) {
suite.tests.forEach(function(test) {
test.pending = true;
});
suite.suites.forEach(function(suite) {
suite.pending = true;
});
// a pending hook won't be executed twice.
hook.pending = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';

describe('outer suite', function () {

before(function () {
console.log('outer before');
});

it('should run this test', function () { });

describe('inner suite', function () {

before(function (done) {
console.log('inner before');
var self = this;
setTimeout(function () {
self.skip();
done();
}, 0);
});

beforeEach(function () {
throw new Error('beforeEach should not run');
});

afterEach(function () {
throw new Error('afterEach should not run');
});

it('should not run this test', function () {
throw new Error('inner suite test should not run');
});

after(function () {
console.log('inner after');
});

describe('skipped suite', function () {
before(function () {
console.log('skipped before');
});

it('should not run this test', function () {
throw new Error('skipped suite test should not run');
});

after(function () {
console.log('skipped after');
});
});

});

it('should run this test', function () { });

after(function () {
console.log('outer after');
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
describe('skip in before with nested describes', function () {
before(function (done) {
var self = this;
setTimeout(function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the necessity of doing this asynchronously?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@boneskull I'm not sure what the "real" use case would look like, but this test validates that an asynchronous skip works with a synchronous nested describe. It seemed like something worth checking, even as an edge case. 🤷‍♀️

Copy link
Contributor

@plroebuck plroebuck May 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many of these setTimeout()-based tests are simply race conditions that happen to have worked in @bannmoore's favor. Shouldn't we just disallow use of async this.skip()? Otherwise, the results are nondeterministic...

Nvm. I should have noticed the done() callback, but missed it initially. I doubt testing the standard Mocha async callback more than once buys us much, but okay. Given setTimeout(func, delay), set delay=0. No point in making the tests any slower than necessary.

self.skip();
done();
}, 0);
});

it('should never run this test', function () {
throw new Error('never run this test');
});

describe('nested describe', function () {
before(function () {
throw new Error('first level before should not run');
});

it('should never run this test', function () {
throw new Error('never run this test');
});

after(function () {
throw new Error('first level after should not run');
});

describe('nested again', function () {
before(function () {
throw new Error('second level before should not run');
});

it('should never run this test', function () {
throw new Error('never run this test');
});

after(function () {
throw new Error('second level after should not run');
});
});
});
});
29 changes: 17 additions & 12 deletions test/integration/fixtures/pending/skip-async-before.fixture.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
'use strict';

describe('skip in before', function () {
before(function (done) {
var self = this;
setTimeout(function () {
self.skip();
}, 50);
});
describe('outer describe', function () {
it('should run this test', function () {});

it('should never run this test', function () {
throw new Error('never thrown');
});
describe('skip in before', function () {
before(function (done) {
var self = this;
setTimeout(function () {
self.skip();
}, 0);
});

it('should never run this test', function () {
throw new Error('never thrown');
it('should never run this test', function () {
throw new Error('never run this test');
});
it('should never run this test', function () {
throw new Error('never run this test');
});
});

it('should run this test', function () {});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ describe('skip in beforeEach', function () {
var self = this;
setTimeout(function () {
self.skip();
}, 50);
done();
}, 0);
});

it('should never run this test', function () {
throw new Error('never thrown');
it('should skip this test', function () {
throw new Error('never run this test');
});

it('should never run this test', function () {
throw new Error('never thrown');
it('should not reach this test', function () {
throw new Error('never run this test');
});
it('should not reach this test', function () {
throw new Error('never run this test');
});
});
6 changes: 2 additions & 4 deletions test/integration/fixtures/pending/skip-async-spec.fixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ describe('skip in test', function () {
var self = this;
setTimeout(function () {
self.skip();
}, 50);
}, 0);
Copy link
Contributor

@plroebuck plroebuck Dec 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove the value. If omitted, 0 is used.

Copy link
Contributor Author

@bannmoore bannmoore Dec 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and I don't see any harm in being explicit, especially in tests.

});

it('should run other tests in the suite', function () {
// Do nothing
});
it('should run other tests in the suite', function () {});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use strict';

describe('outer suite', function () {

before(function () {
console.log('outer before');
});

it('should run this test', function () { });

describe('inner suite', function () {
before(function () {
this.skip();
});

before(function () {
console.log('inner before');
});

beforeEach(function () {
throw new Error('beforeEach should not run');
});

afterEach(function () {
throw new Error('afterEach should not run');
});

after(function () {
console.log('inner after');
});

it('should never run this test', function () {
throw new Error('inner suite test should not run');
});

describe('skipped suite', function () {
before(function () {
console.log('skipped before');
});

it('should never run this test', function () {
throw new Error('skipped suite test should not run');
});

after(function () {
console.log('skipped after');
});
});
});

it('should run this test', function () { });

after(function () {
console.log('outer after');
})

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

describe('skip in before with nested describes', function () {
before(function () {
this.skip();
});

it('should never run this test', function () {
throw new Error('never run this test');
});

describe('nested describe', function () {
before(function () {
throw new Error('first level before should not run');
});

it('should never run this test', function () {
throw new Error('never run this test');
});

after(function () {
throw new Error('first level after should not run');
});

describe('nested again', function () {
before(function () {
throw new Error('second level before should not run');
});

it('should never run this test', function () {
throw new Error('never run this test');
});

after(function () {
throw new Error('second level after should not run');
});
});
});
});
23 changes: 14 additions & 9 deletions test/integration/fixtures/pending/skip-sync-before.fixture.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
'use strict';

describe('skip in before', function () {
before(function () {
this.skip();
});
describe('outer describe', function () {
it('should run this test', function () {});

it('should never run this test', function () {
throw new Error('never thrown');
});
describe('skip in before', function () {
before(function () {
this.skip();
});

it('should never run this test', function () {
throw new Error('never thrown');
it('should never run this test', function () {
throw new Error('never run this test');
});
it('should never run this test', function () {
throw new Error('never run this test');
});
});

it('should run this test', function () {});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ describe('skip in beforeEach', function () {
});

it('should never run this test', function () {
throw new Error('never thrown');
throw new Error('never run this test');
});

it('should never run this test', function () {
throw new Error('never thrown');
throw new Error('never run this test');
});
});
6 changes: 2 additions & 4 deletions test/integration/fixtures/pending/skip-sync-spec.fixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
describe('skip in test', function () {
it('should skip immediately', function () {
this.skip();
throw new Error('never thrown');
throw new Error('never run this test');
});

it('should run other tests in the suite', function () {
// Do nothing
});
it('should run other tests in the suite', function () {});
});
Loading