diff --git a/lib/interfaces/common.js b/lib/interfaces/common.js index ba8b5f85ed..a1612e3eb4 100644 --- a/lib/interfaces/common.js +++ b/lib/interfaces/common.js @@ -145,7 +145,16 @@ module.exports = function (suites, context, mocha) { throw createUnsupportedError('Pending test forbidden'); } if (typeof opts.fn === 'function') { - opts.fn.call(suite); + const suiteResult = opts.fn.call(suite); + if (suiteResult instanceof Promise) { + errors.deprecate( + 'Suite "' + + suite.fullTitle() + + '" returned a Promise. ' + + 'Asynchronous suites are not supported, use a ' + + 'synchronous callback instead.' + ); + } suites.shift(); } else if (typeof opts.fn === 'undefined' && !suite.pending) { throw createMissingArgumentError( diff --git a/test/integration/fixtures/suite/suite-async-callback.fixture.js b/test/integration/fixtures/suite/suite-async-callback.fixture.js new file mode 100644 index 0000000000..b642b22994 --- /dev/null +++ b/test/integration/fixtures/suite/suite-async-callback.fixture.js @@ -0,0 +1,3 @@ +'use strict'; + +describe('a suite with an async callback', async function () {}); diff --git a/test/integration/suite.spec.js b/test/integration/suite.spec.js index 1b4c147261..1507fb0b96 100644 --- a/test/integration/suite.spec.js +++ b/test/integration/suite.spec.js @@ -72,3 +72,24 @@ describe('suite returning a value', function () { ); }); }); + +describe('suite w/async callback', function () { + it('should print a helpful deprecation message when a callback for suite is async', function (done) { + run( + 'suite/suite-async-callback.fixture.js', + args, + function (err, res) { + if (err) { + return done(err); + } + expect( + res.output, + 'to match', + /Asynchronous suites are not supported, use a synchronous callback instead./ + ); + done(); + }, + {stdio: 'pipe'} + ); + }); +});