-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Report skipped tests upon beforeEach hook failure #4233
base: main
Are you sure you want to change the base?
Changes from all commits
1a49fb0
8b1ec51
b70bf5a
eafd390
5cfb8d6
bb10ce9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,6 @@ Mocha is a feature-rich JavaScript test framework running on [Node.js][] and in | |
- [test coverage reporting](#wallabyjs) | ||
- [string diff support](#diffs) | ||
- [javascript API for running tests](#more-information) | ||
- proper exit status for CI support etc | ||
- [auto-detects and disables coloring for non-ttys](#reporters) | ||
- [async test timeout support](#delayed-root-suite) | ||
- [test retry support](#retry-tests) | ||
|
@@ -36,7 +35,6 @@ Mocha is a feature-rich JavaScript test framework running on [Node.js][] and in | |
- [auto-exit to prevent "hanging" with an active loop](#-exit) | ||
- [easily meta-generate suites](#markdown) & [test-cases](#list) | ||
- [config file support](#-config-path) | ||
- clickable suite titles to filter test execution | ||
- [node debugger support](#-inspect-inspect-brk-inspect) | ||
- [node native ES modules support](#nodejs-native-esm-support) | ||
- [detects multiple calls to `done()`](#detects-multiple-calls-to-done) | ||
|
@@ -449,9 +447,73 @@ setTimeout(function() { | |
}, 5000); | ||
``` | ||
|
||
### Failing Hooks | ||
|
||
Upon a failing "before all", "before each" or "after each" hook, all remaining tests in the current suite and also its nested suites will be skipped. Skipped tests are included in the test results and marked as **skipped**. A skipped test is not considered a failed test. | ||
|
||
```js | ||
describe('outer', function() { | ||
before(function() { | ||
throw new Error('Exception in before hook'); | ||
}); | ||
|
||
it('should skip this outer test', function() { | ||
// will be skipped and listed as 'skipped' | ||
}); | ||
|
||
after(function() { | ||
// will be executed | ||
}); | ||
|
||
describe('inner', function() { | ||
before(function() { | ||
// will be skipped | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's important to show (somehow) that order matters. In this case, the outer "before all" hook is run before the inner "before all" hook. If, instead, the inner hook threw, what would happen? |
||
}); | ||
|
||
it('should skip this inner test', function() { | ||
// will be skipped and listed as 'skipped' | ||
}); | ||
|
||
after(function() { | ||
// will be skipped | ||
}); | ||
}); | ||
}); | ||
``` | ||
|
||
#### "before each" hook | ||
|
||
```js | ||
describe('failing "before each" hook', function() { | ||
beforeEach(function() { | ||
// runs and fails only once | ||
throw new Error('Exception in beforeEach hook'); | ||
}); | ||
|
||
it('should skip this outer test', function() { | ||
// will be skipped and reported as 'skipped' test | ||
}); | ||
|
||
afterEach(function() { | ||
/* will be executed */ | ||
}); | ||
after(function() { | ||
/* will be executed */ | ||
}); | ||
|
||
describe('inner suite', function() { | ||
// all hooks, tests and nested suites will be skipped | ||
|
||
it('should skip this inner test', function() { | ||
// will be skipped and reported as 'skipped' test | ||
}); | ||
}); | ||
}); | ||
``` | ||
|
||
## Pending Tests | ||
|
||
"Pending"--as in "someone should write these test cases eventually"--test-cases are simply those _without_ a callback: | ||
"Pending" - as in "someone should write these test cases eventually" - test-cases are simply those _without_ a callback: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this an "EM DASH"? Ideally we should have something like smartypants that translates |
||
|
||
```js | ||
describe('Array', function() { | ||
|
@@ -462,7 +524,9 @@ describe('Array', function() { | |
}); | ||
``` | ||
|
||
Pending tests will be included in the test results, and marked as pending. A pending test is not considered a failed test. | ||
By appending `.skip()`, you may also tell Mocha to ignore a test: [inclusive tests](#inclusive-tests). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: By appending `.skip()`, you may also tell Mocha to [ignore a test](#inclusive-tests). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wait... I'm confused now. I think we could be more clear here. For your consideration:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current situation (incl. this PR) is:
I haven't changed anything on the first item The second label We need two independent labels: pending (or we rename it to skipped) and a new one for hook-failed-omitted tests. So I need to know which name to chose. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit of brainstorm: My thoughts are, when I mark a test not to run, I want Mocha to ignore it, to disable it, to skip it, to omit it. If it's skipped because of hook-failed, Mocha is skipping it, leaving out, or the test was unrun, unused, benched, called off, unprepared, dropped, withdrawn, canceled, halted. And some of this could apply to the previous case as well. I think my favorites so far for hook-failed-omitted are It could be interesting to amass a large number of these potential labels, and run a survey through users of Mocha to see how well they feel each of those words describes (from 1 to 10) those two cases. Not to base our choice on our opinion alone. |
||
|
||
Pending tests will be included in the test results, and marked as **pending**. A pending test is not considered a failed test. | ||
|
||
## Exclusive Tests | ||
|
||
|
@@ -1641,7 +1705,7 @@ mocha.setup({ | |
### Browser-specific Option(s) | ||
|
||
Browser Mocha supports many, but not all [cli options](#command-line-usage). | ||
To use a [cli option](#command-line-usage) that contains a "-", please convert the option to camel-case, (eg. `check-leaks` to `checkLeaks`). | ||
To use a [cli option](#command-line-usage) that contains a "-", please convert the option to camel-case, (e.g. `check-leaks` to `checkLeaks`). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
#### Options that differ slightly from [cli options](#command-line-usage): | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ function Runnable(title, fn) { | |
this._retries = -1; | ||
this._currentRetry = 0; | ||
this.pending = false; | ||
this.skipped = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You know, if we have |
||
} | ||
|
||
/** | ||
|
@@ -166,6 +167,17 @@ Runnable.prototype.isPassed = function() { | |
return !this.isPending() && this.state === constants.STATE_PASSED; | ||
}; | ||
|
||
/** | ||
* Return `true` if this Runnable has been skipped. | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
Runnable.prototype.isSkipped = function() { | ||
return ( | ||
!this.pending && (this.skipped || (this.parent && this.parent.isSkipped())) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should always be a |
||
); | ||
}; | ||
|
||
/** | ||
* Set or get number of retries. | ||
* | ||
|
@@ -270,7 +282,7 @@ Runnable.prototype.run = function(fn) { | |
var finished; | ||
var emitted; | ||
|
||
if (this.isPending()) return fn(); | ||
if (this.isSkipped() || this.isPending()) return fn(); | ||
|
||
// Sometimes the ctx exists, but it is not runnable | ||
if (ctx && ctx.runnable) { | ||
|
@@ -458,7 +470,11 @@ var constants = utils.defineConstants( | |
/** | ||
* Value of `state` prop when a `Runnable` has been skipped by user | ||
*/ | ||
STATE_PENDING: 'pending' | ||
STATE_PENDING: 'pending', | ||
/** | ||
* Value of `state` prop when a `Runnable` has been skipped by failing hook | ||
*/ | ||
STATE_SKIPPED: 'skipped' | ||
} | ||
); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so we're differentiating between "skipped" and "pending"... I know these two concepts have been conflated.