0
# Async Support
1
2
Enhanced async/await and Promise support for test functions and lifecycle hooks, with generator function support and concurrent testing capabilities.
3
4
## Capabilities
5
6
### Async Installation
7
8
Main function that installs async support for all Jasmine test functions and lifecycle hooks.
9
10
```typescript { .api }
11
/**
12
* Installs async/await and Promise support for Jasmine functions
13
* Enhances test functions, lifecycle hooks, and adds concurrent testing support
14
* @param globalConfig - Jest global configuration
15
* @param global - Global object to install async support into
16
*/
17
function jasmineAsyncInstall(
18
globalConfig: Config.GlobalConfig,
19
global: Global.Global,
20
): void;
21
```
22
23
### Promise-based Test Functions
24
25
Test functions automatically support async/await, Promises, and generator functions.
26
27
```typescript { .api }
28
/**
29
* Test function types supporting async patterns
30
*/
31
type TestFn =
32
| ((done: DoneFn) => void) // Callback-based
33
| (() => Promise<void>) // Promise-based
34
| (() => void) // Synchronous
35
| GeneratorFunction; // Generator function
36
37
/**
38
* Done callback for callback-based tests
39
*/
40
interface DoneFn {
41
(): void;
42
fail(error?: any): void;
43
}
44
```
45
46
### Concurrent Testing
47
48
Support for running tests concurrently with controlled concurrency limits.
49
50
```typescript { .api }
51
/**
52
* Concurrent test function interface
53
* Tests marked as concurrent run in parallel up to maxConcurrency limit
54
*/
55
interface ItConcurrentBase {
56
/** Define a concurrent test */
57
(testName: Global.TestNameLike, fn: Global.ConcurrentTestFn, timeout?: number): Spec;
58
59
/** Focused concurrent test (jest-circus only feature, throws in jasmine2) */
60
failing: FailingFn;
61
62
/** Parameterized concurrent tests (installed by jest-each) */
63
each: () => () => void;
64
}
65
66
interface ItConcurrentExtended extends ItConcurrentBase {
67
/** Only run this concurrent test */
68
only: ItConcurrentBase;
69
70
/** Skip this concurrent test */
71
skip: ItConcurrentBase;
72
}
73
74
/**
75
* Concurrent test function that must return a Promise
76
*/
77
type ConcurrentTestFn = () => Promise<unknown>;
78
```
79
80
### Lifecycle Hook Enhancement
81
82
All lifecycle hooks (beforeEach, afterEach, beforeAll, afterAll) support async patterns.
83
84
```typescript { .api }
85
/**
86
* Lifecycle hook function types with async support
87
*/
88
type LifecycleHookFn =
89
| ((done: DoneFn) => void) // Callback-based
90
| (() => Promise<void>) // Promise-based
91
| (() => void) // Synchronous
92
| GeneratorFunction; // Generator function
93
94
/**
95
* Enhanced lifecycle hooks with async support
96
*/
97
interface AsyncLifecycleHooks {
98
beforeEach(fn?: LifecycleHookFn, timeout?: number): void;
99
afterEach(fn?: LifecycleHookFn, timeout?: number): void;
100
beforeAll(fn?: LifecycleHookFn, timeout?: number): void;
101
afterAll(fn?: LifecycleHookFn, timeout?: number): void;
102
}
103
```
104
105
### Generator Function Support
106
107
Support for generator functions using the `co` library for async flow control.
108
109
```typescript { .api }
110
/**
111
* Generator function support via co library
112
* Automatically wraps generator functions for async execution
113
*/
114
type GeneratorFunction = () => Generator<any, any, any>;
115
```
116
117
## Async Patterns
118
119
### Promise-based Tests
120
121
Tests can return Promises directly without using done callbacks.
122
123
**Usage Examples:**
124
125
```typescript
126
// Async/await test
127
it("should handle async operations", async () => {
128
const result = await fetchData();
129
expect(result).toBeDefined();
130
});
131
132
// Promise-based test
133
it("should handle promises", () => {
134
return fetchData().then(result => {
135
expect(result).toBeDefined();
136
});
137
});
138
139
// Generator function test (with co)
140
it("should handle generators", function* () {
141
const result = yield fetchData();
142
expect(result).toBeDefined();
143
});
144
```
145
146
### Async Lifecycle Hooks
147
148
All lifecycle hooks support the same async patterns as tests.
149
150
**Usage Examples:**
151
152
```typescript
153
// Async beforeEach
154
beforeEach(async () => {
155
await setupDatabase();
156
});
157
158
// Promise-based afterEach
159
afterEach(() => {
160
return cleanupResources();
161
});
162
163
// Generator beforeAll
164
beforeAll(function* () {
165
yield initializeApp();
166
});
167
```
168
169
### Concurrent Testing
170
171
Tests can be marked as concurrent to run in parallel.
172
173
**Usage Examples:**
174
175
```typescript
176
// Concurrent test
177
it.concurrent("should run in parallel", async () => {
178
const result = await expensiveOperation();
179
expect(result).toBeDefined();
180
});
181
182
// Concurrent test with timeout
183
it.concurrent("should timeout appropriately", async () => {
184
await longRunningOperation();
185
}, 10000);
186
187
// Concurrent test variations
188
it.concurrent.only("only this concurrent test", async () => {
189
// Only this test runs
190
});
191
192
it.concurrent.skip("skip this concurrent test", async () => {
193
// This test is skipped
194
});
195
```
196
197
### Error Handling
198
199
Enhanced error handling for async operations with proper stack traces.
200
201
```typescript { .api }
202
/**
203
* Error handling for async operations
204
* Preserves stack traces and provides meaningful error messages
205
*/
206
interface AsyncErrorHandling {
207
/** Handles Promise rejections with enhanced stack traces */
208
handlePromiseRejection(error: Error, extraError: Error): void;
209
210
/** Processes generator function errors */
211
handleGeneratorError(error: Error): void;
212
213
/** Validates return values from test functions */
214
validateReturnValue(returnValue: any): void;
215
}
216
```
217
218
## Concurrency Control
219
220
The async installation sets up concurrency control for concurrent tests.
221
222
```typescript { .api }
223
/**
224
* Concurrency control configuration
225
*/
226
interface ConcurrencyControl {
227
/** Maximum number of concurrent tests (from globalConfig.maxConcurrency) */
228
maxConcurrency: number;
229
230
/** Promise queue limiter for concurrent execution */
231
mutex: ReturnType<typeof pLimit>;
232
}
233
```
234
235
**Usage Examples:**
236
237
```typescript
238
// Configure concurrency in Jest config
239
module.exports = {
240
maxConcurrency: 4, // Run up to 4 tests concurrently
241
testRunner: "jest-jasmine2"
242
};
243
244
// Tests automatically respect concurrency limits
245
describe("Concurrent suite", () => {
246
// These will run up to 4 at a time
247
it.concurrent("test 1", async () => { /* ... */ });
248
it.concurrent("test 2", async () => { /* ... */ });
249
it.concurrent("test 3", async () => { /* ... */ });
250
it.concurrent("test 4", async () => { /* ... */ });
251
it.concurrent("test 5", async () => { /* ... */ }); // Waits for slot
252
});
253
```
254
255
## Callback Compatibility
256
257
The async system maintains compatibility with traditional callback-based tests.
258
259
**Usage Examples:**
260
261
```typescript
262
// Traditional done callback
263
it("should work with done callback", (done) => {
264
setTimeout(() => {
265
expect(true).toBe(true);
266
done();
267
}, 100);
268
});
269
270
// Done callback with failure
271
it("should handle done.fail", (done) => {
272
setTimeout(() => {
273
try {
274
expect(false).toBe(true);
275
done();
276
} catch (error) {
277
done.fail(error);
278
}
279
}, 100);
280
});
281
```
282
283
## Failing Tests (Jest Circus Feature)
284
285
Note that `failing` tests are not supported in jest-jasmine2 and will throw an error.
286
287
```typescript { .api }
288
/**
289
* Failing test markers (jest-circus only)
290
* These throw errors in jest-jasmine2
291
*/
292
interface FailingFn {
293
(): never; // Always throws
294
each(): never; // Always throws
295
}
296
```
297
298
**Usage Examples:**
299
300
```typescript
301
// These will throw errors in jest-jasmine2
302
it.failing("this throws an error", () => {
303
// Error: Jest: `failing` tests are only supported in `jest-circus`.
304
});
305
306
it.failing.each([1, 2, 3])("this also throws", (value) => {
307
// Error: Jest: `failing` tests are only supported in `jest-circus`.
308
});
309
```