eslint-plugin-mocha

June 13, 2026 Β· View on GitHub

NPM Version GitHub Actions status Coverage Status NPM Downloads

eslint-plugin-mocha

ESLint rules for Mocha.

This plugin targets Mocha's current JavaScript interfaces documented for Mocha 11. It does not execute Mocha or require Mocha at runtime.

Install

This plugin requires ESLint 10.2.0 or later.

npm install --save-dev eslint-plugin-mocha

Configure

Use the plugin with ESLint's flat config. Apply it only to Mocha test files, and adjust files to match your project:

import mochaPlugin from 'eslint-plugin-mocha';

export default [
    {
        files: [ 'test/**/*.js' ],
        ...mochaPlugin.configs.recommended
    }
];

Configs

  • mochaPlugin.configs.recommended: Practical defaults for most projects.
  • mochaPlugin.configs.all: Enables every rule. This config may change when new rules are added, so it is better suited for trying the full rule set than for stable long-term lint output.
import mochaPlugin from 'eslint-plugin-mocha';

export default [
    {
        files: [ 'test/**/*.js' ],
        ...mochaPlugin.configs.all
    }
];

Plugin settings

These settings are shared by multiple rules.

  • additionalCustomNames: Adds custom suite, test, or hook function names. This is useful for Mocha wrappers such as ember-mocha, mocha-each, or project-specific helpers that wrap setup and teardown. Use interface: "require" for wrappers that expose named imports from a helper module instead of importing directly from mocha.
{
    "rules": {
        "mocha/no-pending-tests": "error",
        "mocha/no-exclusive-tests": "error"
    },
    "settings": {
        "mocha/additionalCustomNames": [
            {
                "name": "describeModule",
                "type": "suite",
                "interface": "BDD"
            },
            {
                "name": "testModule",
                "type": "testCase",
                "interface": "TDD"
            },
            {
                "name": "prepareTestContexts",
                "type": "hook",
                "interface": "BDD"
            }
        ]
    }
}

The name field supports these forms:

  • Plain name, such as describeModule:
describeModule('example', function () {});
  • Dotted name, such as describe.modifier:
describe.modifier('example', function () {});
  • Name with parentheses, such as forEach().describe:
forEach([ 1, 2, 3 ]).describe('example', function (n) {});
  • Combination, such as forEach().describeModule.modifier:
forEach([ 1, 2, 3 ]).describeModule.modifier('example', function (n) {});
  • type: Selects suite, testCase, or hook.
  • interface: Selects BDD, TDD, or require. The default is BDD. With require, rule resolution uses named import statements instead of globals. mocha/consistent-interface also reports named imports of Mocha interface methods when this setting is BDD or TDD, which helps catch accidental require-style usage and interface misconfiguration earlier.

The plugin supports Mocha's BDD, TDD, and Require interfaces. It does not support Mocha's Exports or QUnit interfaces, or third-party UIs with different syntax. Many rules depend on suite, test, and hook calls being represented as nested call expressions, which those interfaces do not provide consistently.

For wrapper APIs that still expose suite, test, or hook call functions, use additionalCustomNames.

Rules

For maintainers: the rules table below is generated, and the headers in documentation/rules/*.md are partly generated. Refresh them with npx just update-eslint-docs. Run mutation testing with npx just test-mutation.

πŸ’Ό Configurations enabled in.
⚠️ Configurations set to warn in.
🚫 Configurations disabled in.
βœ… Set in the recommended configuration.
πŸ”§ Automatically fixable by the --fix CLI option.
πŸ’‘ Manually fixable by editor suggestions.

NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β DescriptionπŸ’Όβš οΈπŸš«πŸ”§πŸ’‘
consistent-interfaceEnforces consistent use of mocha interfacesβœ…πŸ”§
consistent-spacing-between-blocksRequire consistent spacing between blocksβœ…πŸ”§
consistent-structureRequire consistent structure for Mocha test entitiesβœ…
handle-done-callbackEnforces handling of callbacks for async tests in every branchβœ…
limit-retriesEnforce limits for Mocha retriesβœ…
limit-slowEnforce limits for Mocha slow thresholdsβœ…
limit-timeoutEnforce limits for Mocha timeoutsβœ…
max-top-level-suitesEnforce the number of top-level suites in a single fileβœ…
no-async-and-doneDisallow async functions that also use a Mocha callbackβœ…
no-async-in-sync-testsDisallow async operations in synchronous tests or hooksβœ…
no-async-suiteDisallow async functions passed to a suiteβœ…πŸ”§
no-code-after-doneDisallow executing code after calling a Mocha callbackβœ…
no-conditional-testsDisallow conditional suite and test declarationsβœ…
no-done-twiceDisallow calling a Mocha callback more than onceβœ…
no-empty-titleDisallow empty suite and test descriptionsβœ…
no-exclusive-testsDisallow exclusive testsβœ…πŸ’‘
no-exportsDisallow exports from test filesβœ…πŸ’‘
no-hooksDisallow hooksβœ…
no-hooks-for-single-childDisallow hooks with a single direct childβœ…
no-identical-titleDisallow identical titlesβœ…
no-mocha-arrowsDisallow arrow functions as arguments to mocha functionsβœ…πŸ”§
no-nested-suitesDisallow suites to be nested within other suitesβœ…
no-nested-testsDisallow tests to be nested within other testsβœ…
no-pending-testsDisallow pending testsβœ…πŸ’‘
no-return-and-doneDisallow returning in a test or hook function that uses a callbackβœ…
no-return-from-asyncDisallow returning from an async test or hookβœ…
no-root-hooksDisallow root hooksβœ…
no-setup-in-suiteDisallow setup in suite blocksβœ…
no-synchronous-testsDisallow synchronous testsβœ…
no-top-level-testsDisallow top-level testsβœ…
prefer-arrow-callbackRequire using arrow functions for callbacksβœ…πŸ”§
valid-suite-titleRequire suite descriptions to match a pre-configured regular expressionβœ…
valid-test-titleRequire test descriptions to match a pre-configured regular expressionβœ