---
title: Mocha Integration with Mergify
description: Report your test results from Mocha tests to Mergify
---

<IntegrationLogo src={mochaLogo} alt="Mocha logo" />

This guide shows how to generate JUnit reports from your
[Mocha](https://mochajs.org/) tests and upload them to **Test Engine** using
your CI workflow.

## Generate a JUnit report with Mocha

Mocha can write a JUnit XML report with either of two reporters:

- **`xunit`** ships with Mocha. It needs no extra package and works on Mocha 11
  and Mocha 12, including in `--parallel` mode.

- **`mocha-junit-reporter`** is the most widely used third-party JUnit reporter. As
  of version 2.2.1, it crashes on Mocha 12 and in `--parallel` mode, so it only
  suits Mocha 11 or earlier running tests serially.

For a new setup, or if you run Mocha 12 or `--parallel`, use `xunit`. If your
project already uses `mocha-junit-reporter`, you can keep it and set the
options below.

### Using the built-in `xunit` reporter

Set the reporter and its output file in your `.mocharc.yml`:

```yaml
# .mocharc.yml
reporter: xunit
reporter-option:
  - output=junit.xml
```

Or pass them on the command line:

```bash
npx mocha --reporter xunit --reporter-option output=junit.xml
```

With `output` set, `xunit` writes the report to that file and prints nothing to
your terminal. To keep Mocha's usual output as well, see
[Keeping your terminal output](#keeping-your-terminal-output).

### Using `mocha-junit-reporter`

First, install the reporter:

```bash
npm install --save-dev mocha-junit-reporter
```

Then set it in your `.mocharc.yml`:

```yaml
# .mocharc.yml
reporter: mocha-junit-reporter
reporter-option:
  - mochaFile=junit.xml
  - jenkinsMode=true
  - 'suiteTitleSeparatedBy= '
  - includePending=true
```

Or pass the same options on the command line:

```bash
npx mocha --reporter mocha-junit-reporter \
  --reporter-option "mochaFile=junit.xml,jenkinsMode=true,suiteTitleSeparatedBy= ,includePending=true"
```

These options do the following:

- `mochaFile` sets the report's path. Without it, the reporter writes
  `test-results.xml`.

- `jenkinsMode` writes the test's `describe` titles to `classname` and its own
  title to `name`.

- `suiteTitleSeparatedBy`, set to a single space, joins those `describe` titles
  the way `xunit` does, so both reporters give a test the same name. See
  [Test names in Test Engine](#test-names-in-test-engine) for how Test Engine
  builds that name.

- `includePending` reports skipped tests. By default, the reporter leaves them
  out of the file.

### Keeping your terminal output

Mocha runs a single reporter, so pointing it at a JUnit reporter replaces the
output you usually read in your terminal or CI logs. To get both, run them
through `mocha-multi-reporters`:

```bash
npm install --save-dev mocha-multi-reporters
```

Create a `reporter-config.json` that lists the reporters to run. The JUnit
reporter's options go under a key named after it. For `xunit`:

```json
{
  "reporterEnabled": "spec, xunit",
  "xunitReporterOptions": {
    "output": "junit.xml"
  }
}
```

For `mocha-junit-reporter`:

```json
{
  "reporterEnabled": "spec, mocha-junit-reporter",
  "mochaJunitReporterReporterOptions": {
    "mochaFile": "junit.xml",
    "jenkinsMode": true,
    "suiteTitleSeparatedBy": " ",
    "includePending": true
  }
}
```

Replace `spec` with the reporter you use today, then point Mocha at the
configuration file in your `.mocharc.yml`:

```yaml
# .mocharc.yml
reporter: mocha-multi-reporters
reporter-option:
  - configFile=reporter-config.json
```

## Test names in Test Engine

Test Engine names each test from the `classname` and `name` attributes of its
`<testcase>` element, joined with a dot: `<classname>.<name>`. When `classname`
is empty, the test is named `<name>` alone. Test Engine tracks a test's history
under that name, and [quarantine](/test-engine/quarantine) matches failures
against it.

The two reporters fill these attributes differently. Take this test:

```javascript
describe('Cart', function () {
  describe('#add()', function () {
    it('adds an item', function () {
      // ...
    });
  });
});
```

| Attribute | `xunit` | `mocha-junit-reporter`, default options | `mocha-junit-reporter`, options above |
| --- | --- | --- | --- |
| `classname` | `Cart #add()` | `adds an item` | `Cart #add()` |
| `name` | `adds an item` | `Cart #add() adds an item` | `adds an item` |
| Test Engine name | `Cart #add().adds an item` | `adds an item.Cart #add() adds an item` | `Cart #add().adds an item` |

By default, `mocha-junit-reporter` writes the test's own title to `classname`
and its full title to `name`, so the name in Test Engine starts with the test's
title and then repeats it. Setting `testCaseSwitchClassnameAndName` on its own
swaps the two attributes but still repeats the title. `jenkinsMode` writes the
`describe` titles to `classname` instead, joined with a dot unless you set
`suiteTitleSeparatedBy`. With a space, both reporters give every test the same
name, so you can move from `mocha-junit-reporter` to `xunit` later, for
example when you upgrade to Mocha 12, and keep each test's history and
quarantine.

Because a test's name is built from its `describe` and `it` titles:

- Renaming a test or one of its `describe` blocks makes it a new test in Test
  Engine, and a quarantine set on the old name no longer applies.

- Keep values that change between runs, such as timestamps, random IDs or
  generated data, out of titles. Otherwise each run reports a different test.

- Give each test a unique title within its `describe` block. Two tests with the
  same full title share one name, and their results merge.

- A test outside any `describe` block is named by its title alone.

## Update your CI workflow

### GitHub Actions

<CIInsightsSetupNote />

After generating the JUnit report, add a step to upload the results to Test
Engine using the `mergifyio/gha-mergify-ci` action.

With the reporter set in `.mocharc.yml`, run Mocha as usual. For example, in
your workflow file:

```yaml
- name: Run Mocha Tests and Generate JUnit Report
  id: tests
  continue-on-error: true
  run: npx mocha
```

<MergifyCIUploadStep reportPath="junit.xml" />
<MergifyCIUploadStepMatrix reportPath="junit.xml" />

<GhaMergifyCiQuarantineSetup />

### Buildkite

<BuildkiteCIUploadStep reportPath="junit.xml" />
<BuildkiteCIUploadStepMatrix reportPath="junit.xml" />

<BuildkiteTokenNote />

<BuildkiteCIQuarantineSetup />

### Any CI (Mergify CLI)

<MergifyCliUploadStep reportPath="junit.xml" testCommand="npx mocha" />

## Verify and review in Test Engine

After pushing these changes:

1. Your GitHub Actions workflow will execute your Mocha tests.
2. A JUnit report (`junit.xml`) is generated.
3. The Mergify CI action uploads the report to Test Engine.

<ReviewInTestInsights />

## Troubleshooting tips

<ul>
  <li>
    Mocha 12: If the run ends with `TypeError: Class constructor Base cannot be invoked without 'new'`,
    your version of `mocha-junit-reporter` does not support Mocha 12. Switch to the `xunit` reporter.
  </li>

  <li>
    Parallel mode: If `mocha-junit-reporter` fails with
    `TypeError: Cannot read properties of undefined (reading 'testsuite')` when you run with `--parallel`, switch to
    the `xunit` reporter or run your tests serially.
  </li>

  <li>
    No output in the terminal: The `xunit` reporter prints nothing once `output` is set. Use
    `mocha-multi-reporters` to keep your usual reporter, as shown in
    [Keeping your terminal output](#keeping-your-terminal-output).
  </li>

  <CommonTroubleshootingTips />
</ul>
