0
# Test Organization
1
2
Test creation, skipping, planning, and control flow management for organizing test suites with comprehensive test lifecycle control.
3
4
## Capabilities
5
6
### Test Creation
7
8
Core methods for creating and organizing tests with various execution strategies.
9
10
```typescript { .api }
11
/**
12
* Create a new test with the given name and function
13
* @param name - Descriptive name for the test
14
* @param fn - Test function to execute
15
* @returns Promise that resolves when test completes
16
*/
17
function test(name: string, fn?: TestFunction): Promise<void>;
18
19
/**
20
* Create a new test with options
21
* @param name - Descriptive name for the test
22
* @param options - Test configuration options
23
* @param fn - Test function to execute
24
* @returns Promise that resolves when test completes
25
*/
26
function test(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;
27
28
/**
29
* Skip a test - it won't be executed but will appear in output
30
* @param name - Descriptive name for the skipped test
31
* @param fn - Test function (not executed)
32
* @returns Promise that resolves immediately
33
*/
34
function skip(name: string, fn?: TestFunction): Promise<void>;
35
36
/**
37
* Skip a test with options
38
* @param name - Descriptive name for the skipped test
39
* @param options - Test configuration options
40
* @param fn - Test function (not executed)
41
* @returns Promise that resolves immediately
42
*/
43
function skip(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;
44
45
/**
46
* Mark a test as todo - it will run but failures won't cause test suite to fail
47
* @param name - Descriptive name for the todo test
48
* @param fn - Test function to execute
49
* @returns Promise that resolves when test completes
50
*/
51
function todo(name: string, fn?: TestFunction): Promise<void>;
52
53
/**
54
* Mark a test as todo with options
55
* @param name - Descriptive name for the todo test
56
* @param options - Test configuration options
57
* @param fn - Test function to execute
58
* @returns Promise that resolves when test completes
59
*/
60
function todo(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;
61
62
/**
63
* Run only this test (requires filter plugin) - other tests will be skipped
64
* @param name - Descriptive name for the test
65
* @param fn - Test function to execute
66
* @returns Promise that resolves when test completes
67
*/
68
function only(name: string, fn?: TestFunction): Promise<void>;
69
70
/**
71
* Run only this test with options
72
* @param name - Descriptive name for the test
73
* @param options - Test configuration options
74
* @param fn - Test function to execute
75
* @returns Promise that resolves when test completes
76
*/
77
function only(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;
78
```
79
80
**Usage Examples:**
81
82
```typescript
83
import { test, skip, todo, only } from "tap";
84
85
// Basic test
86
test("addition works", (t) => {
87
t.equal(2 + 2, 4);
88
t.end();
89
});
90
91
// Test with options
92
test("async test", { timeout: 5000 }, async (t) => {
93
const result = await asyncOperation();
94
t.ok(result.success);
95
});
96
97
// Skip a test
98
skip("not implemented yet", (t) => {
99
// This won't run
100
t.fail("should not run");
101
t.end();
102
});
103
104
// Todo test - runs but failures don't fail the suite
105
todo("fix this later", (t) => {
106
t.fail("known issue"); // Won't cause suite failure
107
t.end();
108
});
109
110
// Only run this test (requires --only flag or filter plugin)
111
only("debug this test", (t) => {
112
t.ok(true);
113
t.end();
114
});
115
```
116
117
### Test Control
118
119
Methods for controlling test execution flow and planning.
120
121
```typescript { .api }
122
/**
123
* Set the expected number of assertions in this test
124
* @param count - Number of assertions expected
125
*/
126
function plan(count: number): void;
127
128
/**
129
* Explicitly end the test - useful for async tests
130
*/
131
function end(): void;
132
133
/**
134
* Bail out of the entire test run with an optional reason
135
* @param reason - Optional reason for bailing out
136
*/
137
function bailout(reason?: string): void;
138
139
/**
140
* Set timeout for the current test in milliseconds
141
* @param ms - Timeout in milliseconds
142
*/
143
function timeout(ms: number): void;
144
145
/**
146
* Add a comment to the TAP output stream
147
* @param message - Comment message
148
*/
149
function comment(message: string): void;
150
151
/**
152
* Add a pragma directive to the TAP output
153
* @param pragma - Pragma directive
154
*/
155
function pragma(pragma: string): void;
156
```
157
158
**Usage Examples:**
159
160
```typescript
161
// Planned test - expects exactly 3 assertions
162
test("planned test", (t) => {
163
t.plan(3);
164
t.ok(true, "first assertion");
165
t.ok(true, "second assertion");
166
t.ok(true, "third assertion");
167
// Test ends automatically after 3 assertions
168
});
169
170
// Explicit end for async tests
171
test("async test with explicit end", (t) => {
172
setTimeout(() => {
173
t.ok(true, "delayed assertion");
174
t.end(); // Explicitly end the test
175
}, 100);
176
});
177
178
// Test with timeout
179
test("timeout test", (t) => {
180
t.timeout(1000); // 1 second timeout
181
// Test will fail if it takes longer than 1 second
182
t.ok(true);
183
t.end();
184
});
185
186
// Adding comments and pragmas
187
test("documented test", (t) => {
188
t.comment("Starting the test");
189
t.pragma("version 14");
190
t.ok(true);
191
t.comment("Test completed successfully");
192
t.end();
193
});
194
195
// Bail out example (use sparingly)
196
test("critical test", (t) => {
197
if (!criticalCondition) {
198
t.bailout("Critical condition not met, cannot continue");
199
return;
200
}
201
t.ok(true);
202
t.end();
203
});
204
```
205
206
### Nested Tests
207
208
TAP supports nested test structures for organizing related tests.
209
210
```typescript
211
test("parent test", (t) => {
212
t.test("child test 1", (ct) => {
213
ct.ok(true, "child assertion");
214
ct.end();
215
});
216
217
t.test("child test 2", (ct) => {
218
ct.equal(1 + 1, 2, "math works in child");
219
ct.end();
220
});
221
222
t.end();
223
});
224
```
225
226
### Test Options
227
228
```typescript { .api }
229
interface TestOpts {
230
/** Override the test name */
231
name?: string;
232
233
/** Timeout in milliseconds for this test */
234
timeout?: number;
235
236
/** Skip this test (boolean or reason string) */
237
skip?: boolean | string;
238
239
/** Mark as todo (boolean or reason string) */
240
todo?: boolean | string;
241
242
/** Run only this test (requires filter plugin) */
243
only?: boolean;
244
245
/** Bail out on first failure in this test */
246
bail?: boolean;
247
248
/** Run test even if parent test fails */
249
autoend?: boolean;
250
251
/** Buffer output until test completes */
252
buffered?: boolean;
253
}
254
255
type TestFunction = (t: TAP) => void | Promise<void>;
256
```
257
258
**Usage Examples:**
259
260
```typescript
261
// Test with multiple options
262
test("complex test", {
263
timeout: 5000,
264
skip: process.env.SKIP_SLOW_TESTS === "true",
265
bail: true
266
}, async (t) => {
267
await complexAsyncOperation();
268
t.ok(true);
269
t.end();
270
});
271
272
// Conditional skip
273
test("platform specific test", {
274
skip: process.platform === "win32" ? "Not supported on Windows" : false
275
}, (t) => {
276
t.ok(true);
277
t.end();
278
});
279
280
// Todo with reason
281
test("future feature", {
282
todo: "Waiting for API changes"
283
}, (t) => {
284
t.ok(false, "This will fail but won't fail the suite");
285
t.end();
286
});
287
```
288
289
### Subtests vs Top-Level Tests
290
291
TAP distinguishes between top-level tests and subtests:
292
293
```typescript
294
// Top-level test - runs in its own process
295
test("top level", (t) => {
296
// This runs in a separate process
297
t.ok(true);
298
299
// Subtest - runs in the same process as parent
300
t.test("subtest", (st) => {
301
st.ok(true);
302
st.end();
303
});
304
305
t.end();
306
});
307
```
308
309
### Test Filtering
310
311
When using the filter plugin, you can control which tests run:
312
313
```typescript
314
// Only run tests marked with 'only'
315
test("normal test", (t) => {
316
// Skipped when --only is used
317
t.ok(true);
318
t.end();
319
});
320
321
only("focused test", (t) => {
322
// Only this runs when --only is used
323
t.ok(true);
324
t.end();
325
});
326
```
327
328
### Asynchronous Test Patterns
329
330
TAP supports several patterns for async testing:
331
332
```typescript
333
// Promise-based test
334
test("promise test", async (t) => {
335
const result = await fetchData();
336
t.ok(result.success);
337
// No need to call t.end() with async functions
338
});
339
340
// Callback-based test with explicit end
341
test("callback test", (t) => {
342
fetchDataWithCallback((err, result) => {
343
t.error(err);
344
t.ok(result.success);
345
t.end(); // Must call end() for non-async functions
346
});
347
});
348
349
// Mixed async/sync with planning
350
test("mixed test", (t) => {
351
t.plan(2);
352
t.ok(true, "sync assertion");
353
354
setTimeout(() => {
355
t.ok(true, "async assertion");
356
// Test ends after 2 assertions due to plan
357
}, 100);
358
});
359
```