0
# Test Organization and Interfaces
1
2
Mocha supports multiple interfaces for organizing and writing tests. Each interface provides a different syntax style and mental model for structuring test suites and cases.
3
4
## Capabilities
5
6
### BDD Interface (Default)
7
8
Behavior Driven Development interface using `describe` and `it` functions. This is the default interface and most commonly used.
9
10
```javascript { .api }
11
/**
12
* Define a test suite
13
* @param title - Suite title/description
14
* @param fn - Suite implementation function
15
*/
16
function describe(title, fn);
17
18
/**
19
* Define a test case
20
* @param title - Test title/description
21
* @param fn - Test implementation function
22
*/
23
function it(title, fn);
24
25
/**
26
* Define aliases for describe and it
27
*/
28
function context(title, fn); // alias for describe
29
function specify(title, fn); // alias for it
30
31
/**
32
* Define hooks that run before/after suites and tests
33
*/
34
function before(fn); // runs once before all tests in suite
35
function after(fn); // runs once after all tests in suite
36
function beforeEach(fn); // runs before each test
37
function afterEach(fn); // runs after each test
38
39
/**
40
* Exclusive execution - only run marked tests/suites
41
*/
42
function describe.only(title, fn);
43
function it.only(title, fn);
44
function context.only(title, fn);
45
function specify.only(title, fn);
46
47
/**
48
* Skip tests/suites - do not execute
49
*/
50
function describe.skip(title, fn);
51
function it.skip(title, fn);
52
function context.skip(title, fn);
53
function specify.skip(title, fn);
54
55
/**
56
* Skip aliases using x prefix
57
*/
58
function xdescribe(title, fn); // alias for describe.skip
59
function xit(title, fn); // alias for it.skip
60
function xcontext(title, fn); // alias for context.skip
61
function xspecify(title, fn); // alias for specify.skip
62
```
63
64
**Usage Example:**
65
66
```javascript
67
const assert = require('assert');
68
69
describe('Calculator', function() {
70
let calculator;
71
72
before(function() {
73
// Setup before all tests
74
calculator = new Calculator();
75
});
76
77
beforeEach(function() {
78
// Reset state before each test
79
calculator.reset();
80
});
81
82
describe('#add()', function() {
83
it('should add two positive numbers', function() {
84
const result = calculator.add(2, 3);
85
assert.equal(result, 5);
86
});
87
88
it('should handle negative numbers', function() {
89
const result = calculator.add(-1, 1);
90
assert.equal(result, 0);
91
});
92
93
it.skip('should handle decimal numbers', function() {
94
// This test is skipped
95
});
96
});
97
98
describe.only('#multiply()', function() {
99
// Only this suite will run when using .only
100
it('should multiply two numbers', function() {
101
const result = calculator.multiply(3, 4);
102
assert.equal(result, 12);
103
});
104
});
105
});
106
```
107
108
### TDD Interface
109
110
Test Driven Development interface using `suite` and `test` functions.
111
112
```javascript { .api }
113
/**
114
* Define a test suite (equivalent to describe)
115
* @param title - Suite title/description
116
* @param fn - Suite implementation function
117
*/
118
function suite(title, fn);
119
120
/**
121
* Define a test case (equivalent to it)
122
* @param title - Test title/description
123
* @param fn - Test implementation function
124
*/
125
function test(title, fn);
126
127
/**
128
* Define hooks for setup and teardown
129
*/
130
function setup(fn); // equivalent to beforeEach
131
function teardown(fn); // equivalent to afterEach
132
function suiteSetup(fn); // equivalent to before
133
function suiteTeardown(fn); // equivalent to after
134
135
/**
136
* Exclusive execution modifiers
137
*/
138
function suite.only(title, fn);
139
function test.only(title, fn);
140
141
/**
142
* Skip modifiers
143
*/
144
function suite.skip(title, fn);
145
function test.skip(title, fn);
146
```
147
148
**Usage Example:**
149
150
```javascript
151
const assert = require('assert');
152
153
suite('Calculator TDD', function() {
154
let calculator;
155
156
suiteSetup(function() {
157
calculator = new Calculator();
158
});
159
160
setup(function() {
161
calculator.reset();
162
});
163
164
suite('Addition', function() {
165
test('should add positive numbers', function() {
166
const result = calculator.add(2, 3);
167
assert.equal(result, 5);
168
});
169
170
test('should add negative numbers', function() {
171
const result = calculator.add(-2, -3);
172
assert.equal(result, -5);
173
});
174
});
175
176
teardown(function() {
177
// Cleanup after each test
178
});
179
});
180
```
181
182
### QUnit Interface
183
184
QUnit-style interface providing `suite` and `test` functions with QUnit-compatible hooks.
185
186
```javascript { .api }
187
/**
188
* Define a test suite
189
* @param title - Suite title/description
190
* @param fn - Suite implementation function
191
*/
192
function suite(title, fn);
193
194
/**
195
* Define a test case
196
* @param title - Test title/description
197
* @param fn - Test implementation function
198
*/
199
function test(title, fn);
200
201
/**
202
* Define hooks
203
*/
204
function before(fn); // runs before all tests in suite
205
function after(fn); // runs after all tests in suite
206
function beforeEach(fn); // runs before each test
207
function afterEach(fn); // runs after each test
208
209
/**
210
* Exclusive and skip modifiers
211
*/
212
function suite.only(title, fn);
213
function test.only(title, fn);
214
function suite.skip(title, fn);
215
function test.skip(title, fn);
216
```
217
218
### Exports Interface
219
220
Node.js module.exports style interface where test structure is defined using object properties.
221
222
```javascript { .api }
223
/**
224
* Exports interface uses object properties to define test structure
225
* No global functions - tests are defined as object methods
226
*/
227
228
// Example structure:
229
module.exports = {
230
'Calculator': {
231
'before': function() {
232
// Setup
233
},
234
235
'#add()': {
236
'should add positive numbers': function() {
237
// Test implementation
238
},
239
240
'should add negative numbers': function() {
241
// Test implementation
242
}
243
},
244
245
'#multiply()': {
246
'should multiply numbers': function() {
247
// Test implementation
248
}
249
},
250
251
'after': function() {
252
// Teardown
253
}
254
}
255
};
256
```
257
258
**Usage Example:**
259
260
```javascript
261
const assert = require('assert');
262
const Calculator = require('./calculator');
263
264
module.exports = {
265
'Calculator Tests': {
266
before: function() {
267
this.calculator = new Calculator();
268
},
269
270
'Addition Tests': {
271
beforeEach: function() {
272
this.calculator.reset();
273
},
274
275
'should add two positive numbers': function() {
276
const result = this.calculator.add(2, 3);
277
assert.equal(result, 5);
278
},
279
280
'should handle zero': function() {
281
const result = this.calculator.add(5, 0);
282
assert.equal(result, 5);
283
}
284
},
285
286
'Multiplication Tests': {
287
'should multiply positive numbers': function() {
288
const result = this.calculator.multiply(3, 4);
289
assert.equal(result, 12);
290
}
291
}
292
}
293
};
294
```
295
296
### Interface Selection
297
298
```javascript { .api }
299
/**
300
* Set the interface for a Mocha instance or globally
301
* @param name - Interface name: 'bdd', 'tdd', 'qunit', 'exports'
302
*/
303
mocha.ui(name);
304
305
// Available interfaces
306
const interfaces = {
307
bdd: require('mocha/lib/interfaces/bdd'),
308
tdd: require('mocha/lib/interfaces/tdd'),
309
qunit: require('mocha/lib/interfaces/qunit'),
310
exports: require('mocha/lib/interfaces/exports')
311
};
312
```
313
314
### Global Function Aliases
315
316
All interfaces provide these global function aliases for compatibility:
317
318
```javascript { .api }
319
// These functions delegate to the current interface
320
function describe(title, fn); // maps to current interface's suite function
321
function it(title, fn); // maps to current interface's test function
322
function before(fn); // maps to current interface's before hook
323
function after(fn); // maps to current interface's after hook
324
function beforeEach(fn); // maps to current interface's beforeEach hook
325
function afterEach(fn); // maps to current interface's afterEach hook
326
327
// TDD aliases (always available)
328
function suite(title, fn); // alias for describe
329
function test(title, fn); // alias for it
330
function setup(fn); // alias for beforeEach
331
function teardown(fn); // alias for afterEach
332
function suiteSetup(fn); // alias for before
333
function suiteTeardown(fn); // alias for after
334
335
// Skip aliases
336
function xdescribe(title, fn); // alias for describe.skip
337
function xit(title, fn); // alias for it.skip
338
339
// Programmatic execution
340
function run(); // trigger test execution
341
```
342
343
### Interface Configuration
344
345
Interfaces can be configured when creating a Mocha instance:
346
347
```javascript
348
const mocha = new Mocha({
349
ui: 'tdd', // Use TDD interface
350
// other options...
351
});
352
353
// Or set programmatically
354
mocha.ui('bdd');
355
```