mocha-ui-esm
v1.0.0
Published
A test interface for esmodules with Mocha
Maintainers
Readme
mocha-ui-esm
A modern Mocha UI that allows you to define tests using ES Modules (ESM). It supports multiple test styles including Classes, Objects, and Functions, leveraging the powerful esm-test-parser.
Contents
Installation
npm install mocha-ui-esm --save-devUsage
1. Register the UI
In your test runner, register the UI before initializing Mocha.
// runner.js
import Mocha from 'mocha';
import { registerMochaUiEsm } from 'mocha-ui-esm';
import * as MyTests from './tests.js';
// Register the 'esm' interface
registerMochaUiEsm(Mocha.interfaces);
// Create the runner
const mocha = new Mocha({
ui: 'esm',
reporter: 'spec'
});
// Emit your test modules to the suite
mocha.suite.emit('modules', MyTests);
mocha.run(failures => process.exit(failures ? 1 : 0));2. Configuration
You can pass options to registerMochaUiEsm to customize the behavior.
// runner.js
import Mocha from 'mocha';
import { SortByEnum, registerMochaUiEsm } from 'mocha-ui-esm';
registerMochaUiEsm(Mocha.interfaces, {
classContextPropertyName: 'suiteContext', // Default
sort: SortByEnum.byTitle, // Sort tests by title
parserFlags: {
allowLiteralTitle: true
}
});MochaUiEsmOptions
| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| classContextPropertyName | string | "suiteContext" | The property name used to access the Mocha context in class instances. |
| sort | SortByEnum | "none" | Sorting strategy: "none", "byGroup", "byTitle", "byTitleAndGroup". |
| testCaseTitleTemplate | Function | internal | Custom function to generate titles for parameterized tests. |
| parserFlags | Object | {...} | Flags for the underlying esm-test-parser. |
Test Styles with Examples
mocha-ui-esm supports three primary styles for defining your tests, each with its own advantages.
1. Test Objects (Hierarchical & Declarative)
Objects are ideal for hierarchical grouping where keys automatically define the structure and titles of the test suite.
- Hierarchical Grouping: Organize tests into logical suites using nested structures.
- Implicit Titles: Object keys serve as test and group titles.
- Sequential Filtering: Use
only: true,only: number, oronly: '*'within the object to control execution. - Parameterized Tests: Use arrays of arguments to define multiple cases for a single key.
// tests.js
import assert from 'assert';
import { test } from 'mocha-ui-esm';
export const MyMathTests = {
[test.title]: "Math Suite",
only: true, // Optional. runs the 'Basic Operations' suite in isolation
'Basic Operations': {
'Addition': {
'1 + 1 = 2': () => { assert.strictEqual(1 + 1, 2); },
},
},
// only: '*', // Optional. runs all remaining tests in the current suite in isolation
// Parameterized test: Runs for each array entry
'Calculate Square Root ($i)': [
[9, 3],
[16, 4],
function(input, expected) {
assert.strictEqual(Math.sqrt(input), expected);
}
]
};2. Test Classes (Stateful & Declarative)
Classes provide a declarative, stateful approach to testing, utilizing decorators for metadata.
- Declarative Testing: Classes act as suites and methods act as tests.
- Decorators: Use
@testCase,@testOnly, and@testTitlefor clean definitions. - Instance Context: Tests run within the class instance, allowing shared state via
this. - Context Injection: Access the Mocha context via
this.suiteContext(default name).
// tests.js
import assert from 'assert';
import { testTitle, testCase, testOnly } from 'mocha-ui-esm';
@testTitle('Math Suite')
export class MathTests {
suiteContext: any;
@testCase(1, 1, 2)
@testCase(2, 3, 5)
'add $1 + $2 = $3'(a, b, expected) {
assert.strictEqual(a + b, expected);
}
@testOnly()
onlyThisTest() {
assert.ok(true);
}
}3. Pure Test Functions (Functional & Simple)
Functional tests treat exported functions as individual tests, with metadata attached directly to the function objects.
- Automatic Discovery: All exported functions (except reserved hooks) are treated as tests.
- Metadata via Properties: Attach
[test.title],[test.cases], and[only]directly to the function. - Reserved Hooks: Export functions named
beforeEach,afterEach, etc., for setup/teardown.
// tests.js
import assert from 'assert';
import { only, test } from 'mocha-ui-esm';
export function basicTest() {
assert.ok(true);
}
// Attach metadata to the function object
customTest[only] = true;
customTest[test.title] = "This is a custom title";
export function customTest() {
assert.ok(true);
}
// Parameterized functional test
parameterizedTest[test.cases] = [[1, 1], [2, 4]];
export function parameterizedTest(val, expected) {
assert.strictEqual(val * val, expected);
}
export function beforeAll() {
// Runs before all tests in this module
}

