0
# Test Environment Setup
1
2
The test environment functionality provides utilities for creating and configuring Yeoman environments specifically optimized for testing. This includes custom test adapters, shared file systems, and environment-specific configuration options that ensure isolated and predictable test execution.
3
4
## Capabilities
5
6
### Environment Creation
7
8
Create Yeoman environments configured for testing scenarios.
9
10
```typescript { .api }
11
/**
12
* Create a standard Yeoman environment
13
* @param options - Base environment options
14
* @returns Promise resolving to environment instance
15
*/
16
async createEnv(options: BaseEnvironmentOptions): Promise<DefaultEnvironmentApi>;
17
18
/**
19
* Creates a test environment with TestAdapter and testing-specific configuration
20
* @param environmentConstructor - Optional custom environment constructor
21
* @param options - Environment options (defaults include localConfigOnly: true)
22
* @returns Promise resolving to configured test environment
23
*/
24
async createTestEnv(
25
environmentConstructor?: CreateEnv,
26
options?: BaseEnvironmentOptions
27
): Promise<DefaultEnvironmentApi>;
28
29
type CreateEnv = (options: BaseEnvironmentOptions) => Promise<BaseEnvironment>;
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import helpers from "yeoman-test";
36
37
// Basic environment
38
const env = await helpers.createEnv({
39
cwd: process.cwd(),
40
force: true
41
});
42
43
// Test environment with defaults
44
const testEnv = await helpers.createTestEnv();
45
46
// Custom test environment
47
const customTestEnv = await helpers.createTestEnv(
48
// Custom environment constructor
49
(options) => new CustomEnvironment(options),
50
// Custom options
51
{
52
localConfigOnly: false,
53
skipCache: false,
54
cwd: "/custom/path"
55
}
56
);
57
```
58
59
### Test Adapter Creation
60
61
Create and configure TestAdapter instances for prompt mocking and interaction simulation.
62
63
```typescript { .api }
64
/**
65
* Creates a TestAdapter using default options
66
* @param options - Optional adapter configuration
67
* @returns TestAdapter instance configured for testing
68
*/
69
createTestAdapter(options?: TestAdapterOptions): TestAdapter;
70
71
class TestAdapter extends BaseTestAdapter {
72
constructor(options?: TestAdapterOptions);
73
}
74
```
75
76
**Usage Examples:**
77
78
```typescript
79
import helpers from "yeoman-test";
80
81
// Basic test adapter
82
const adapter = helpers.createTestAdapter();
83
84
// Configured test adapter
85
const adapter = helpers.createTestAdapter({
86
mockedAnswers: {
87
projectName: "test-app",
88
features: ["typescript", "testing"]
89
},
90
throwOnMissingAnswer: true,
91
callback: (answer, options) => {
92
console.log(`Answered ${options.question.name}: ${answer}`);
93
return answer;
94
}
95
});
96
97
// Use with custom environment
98
const env = await helpers.createEnv({
99
adapter,
100
force: true
101
});
102
```
103
104
## Environment Configuration Options
105
106
### BaseEnvironmentOptions
107
108
Standard Yeoman environment options that can be used with test environments.
109
110
```typescript { .api }
111
interface BaseEnvironmentOptions {
112
/** Current working directory for the environment */
113
cwd?: string;
114
115
/** Force overwrite existing files */
116
force?: boolean;
117
118
/** Skip generator lookup caching */
119
skipCache?: boolean;
120
121
/** Skip automatic npm/yarn install */
122
skipInstall?: boolean;
123
124
/** Use local configuration only */
125
localConfigOnly?: boolean;
126
127
/** Custom adapter instance */
128
adapter?: any;
129
130
/** Shared file system instance */
131
sharedFs?: any;
132
133
/** Additional shared options for generators */
134
sharedOptions?: Record<string, any>;
135
136
/** Enable new error handler */
137
newErrorHandler?: boolean;
138
}
139
```
140
141
### TestAdapterOptions
142
143
Configuration options specific to the TestAdapter for prompt mocking.
144
145
```typescript { .api }
146
interface TestAdapterOptions {
147
/** Pre-configured answers for prompts */
148
mockedAnswers?: PromptAnswers;
149
150
/** Throw error if no answer provided for a prompt */
151
throwOnMissingAnswer?: boolean;
152
153
/** Callback function called for each prompt answer */
154
callback?: DummyPromptCallback;
155
156
/** Custom spy factory for creating mocks */
157
spyFactory?: (options: { returns?: any }) => any;
158
}
159
160
type DummyPromptCallback = (
161
this: any,
162
answer: any,
163
options: { question: any }
164
) => any;
165
166
type PromptAnswers = Record<string, any>;
167
```
168
169
## Advanced Environment Patterns
170
171
### Custom Environment Integration
172
173
```typescript
174
import helpers from "yeoman-test";
175
import CustomEnvironment from "./custom-environment";
176
177
// Use custom environment class
178
const env = await helpers.createTestEnv(
179
(options) => new CustomEnvironment(options),
180
{
181
cwd: process.cwd(),
182
customFeature: true
183
}
184
);
185
186
// Register generators
187
env.register("./path/to/generator", { namespace: "my:gen" });
188
189
// Create generator instance
190
const generator = await env.create("my:gen", {
191
generatorArgs: ["init"],
192
generatorOptions: { force: true }
193
});
194
```
195
196
### Shared File System Configuration
197
198
```typescript
199
import { create as createMemFs } from "mem-fs";
200
import helpers from "yeoman-test";
201
202
// Create shared file system
203
const sharedFs = createMemFs();
204
205
// Use with multiple environments
206
const env1 = await helpers.createTestEnv(undefined, {
207
sharedFs,
208
cwd: "/test/dir1"
209
});
210
211
const env2 = await helpers.createTestEnv(undefined, {
212
sharedFs,
213
cwd: "/test/dir2"
214
});
215
216
// Both environments share the same file system
217
```
218
219
### Environment Event Handling
220
221
```typescript
222
const env = await helpers.createTestEnv();
223
224
// Listen for environment events
225
env.on("compose", (namespace, generator) => {
226
console.log(`Composing with ${namespace}`);
227
});
228
229
env.on("error", (error) => {
230
console.error("Environment error:", error);
231
});
232
233
// Register and run generator
234
env.register("./my-generator", { namespace: "my:app" });
235
const generator = await env.create("my:app");
236
await env.runGenerator(generator);
237
```
238
239
### Prompt Mock Configuration
240
241
```typescript
242
import helpers from "yeoman-test";
243
244
// Advanced prompt mocking
245
const adapter = helpers.createTestAdapter({
246
mockedAnswers: {
247
projectName: "my-project",
248
features: ["typescript", "testing"],
249
author: "Test Author"
250
},
251
252
throwOnMissingAnswer: true,
253
254
callback: (answer, { question }) => {
255
// Log all prompt interactions
256
console.log(`Question: ${question.message}`);
257
console.log(`Answer: ${answer}`);
258
259
// Modify answers based on question
260
if (question.name === "projectName") {
261
return answer.toLowerCase().replace(/\s+/g, "-");
262
}
263
264
return answer;
265
}
266
});
267
268
const env = await helpers.createTestEnv(undefined, { adapter });
269
```
270
271
## Integration with RunContext
272
273
The test environment functionality integrates seamlessly with RunContext:
274
275
```typescript
276
import helpers from "yeoman-test";
277
278
// Environment configuration flows through to RunContext
279
await helpers.run("my-generator", {
280
// RunContext settings
281
tmpdir: true,
282
namespace: "my:app"
283
}, {
284
// Environment options
285
localConfigOnly: false,
286
skipInstall: false,
287
force: true
288
});
289
290
// Custom environment constructor
291
const customEnvFactory = (options) => new CustomEnvironment(options);
292
293
await helpers.run("my-generator", {}, {
294
createEnv: customEnvFactory,
295
cwd: "/custom/path"
296
});
297
```
298
299
## Testing Environment Behavior
300
301
```typescript
302
describe("environment behavior", () => {
303
let env: DefaultEnvironmentApi;
304
305
beforeEach(async () => {
306
env = await helpers.createTestEnv({
307
localConfigOnly: true,
308
force: true
309
});
310
});
311
312
it("registers generators correctly", () => {
313
env.register("./path/to/generator", { namespace: "my:gen" });
314
315
const registered = env.getRegisteredPackages();
316
expect(registered).toHaveProperty("my:gen");
317
});
318
319
it("creates generators with options", async () => {
320
env.register("./my-generator", { namespace: "my:app" });
321
322
const generator = await env.create("my:app", {
323
generatorArgs: ["init", "--force"],
324
generatorOptions: { skipInstall: true }
325
});
326
327
expect(generator.options.skipInstall).toBe(true);
328
});
329
});
330
```
331
332
## Default Environment Behavior
333
334
Test environments created with `createTestEnv` include these defaults:
335
336
- **TestAdapter**: Automatically configured for prompt mocking
337
- **localConfigOnly: true**: Prevents global configuration interference
338
- **newErrorHandler: true**: Enhanced error handling for better test debugging
339
- **Isolated file system**: Uses mem-fs for safe file operations
340
- **Skip behaviors**: Cache and install skipping enabled by default
341
342
These defaults ensure consistent, isolated test execution while maintaining the flexibility to override any behavior when needed.