Test utilities for Yeoman generators providing a fluent API for setting up test environments and asserting generated content
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.
Create Yeoman environments configured for testing scenarios.
/**
* Create a standard Yeoman environment
* @param options - Base environment options
* @returns Promise resolving to environment instance
*/
async createEnv(options: BaseEnvironmentOptions): Promise<DefaultEnvironmentApi>;
/**
* Creates a test environment with TestAdapter and testing-specific configuration
* @param environmentConstructor - Optional custom environment constructor
* @param options - Environment options (defaults include localConfigOnly: true)
* @returns Promise resolving to configured test environment
*/
async createTestEnv(
environmentConstructor?: CreateEnv,
options?: BaseEnvironmentOptions
): Promise<DefaultEnvironmentApi>;
type CreateEnv = (options: BaseEnvironmentOptions) => Promise<BaseEnvironment>;Usage Examples:
import helpers from "yeoman-test";
// Basic environment
const env = await helpers.createEnv({
cwd: process.cwd(),
force: true
});
// Test environment with defaults
const testEnv = await helpers.createTestEnv();
// Custom test environment
const customTestEnv = await helpers.createTestEnv(
// Custom environment constructor
(options) => new CustomEnvironment(options),
// Custom options
{
localConfigOnly: false,
skipCache: false,
cwd: "/custom/path"
}
);Create and configure TestAdapter instances for prompt mocking and interaction simulation.
/**
* Creates a TestAdapter using default options
* @param options - Optional adapter configuration
* @returns TestAdapter instance configured for testing
*/
createTestAdapter(options?: TestAdapterOptions): TestAdapter;
class TestAdapter extends BaseTestAdapter {
constructor(options?: TestAdapterOptions);
}Usage Examples:
import helpers from "yeoman-test";
// Basic test adapter
const adapter = helpers.createTestAdapter();
// Configured test adapter
const adapter = helpers.createTestAdapter({
mockedAnswers: {
projectName: "test-app",
features: ["typescript", "testing"]
},
throwOnMissingAnswer: true,
callback: (answer, options) => {
console.log(`Answered ${options.question.name}: ${answer}`);
return answer;
}
});
// Use with custom environment
const env = await helpers.createEnv({
adapter,
force: true
});Standard Yeoman environment options that can be used with test environments.
interface BaseEnvironmentOptions {
/** Current working directory for the environment */
cwd?: string;
/** Force overwrite existing files */
force?: boolean;
/** Skip generator lookup caching */
skipCache?: boolean;
/** Skip automatic npm/yarn install */
skipInstall?: boolean;
/** Use local configuration only */
localConfigOnly?: boolean;
/** Custom adapter instance */
adapter?: any;
/** Shared file system instance */
sharedFs?: any;
/** Additional shared options for generators */
sharedOptions?: Record<string, any>;
/** Enable new error handler */
newErrorHandler?: boolean;
}Configuration options specific to the TestAdapter for prompt mocking.
interface TestAdapterOptions {
/** Pre-configured answers for prompts */
mockedAnswers?: PromptAnswers;
/** Throw error if no answer provided for a prompt */
throwOnMissingAnswer?: boolean;
/** Callback function called for each prompt answer */
callback?: DummyPromptCallback;
/** Custom spy factory for creating mocks */
spyFactory?: (options: { returns?: any }) => any;
}
type DummyPromptCallback = (
this: any,
answer: any,
options: { question: any }
) => any;
type PromptAnswers = Record<string, any>;import helpers from "yeoman-test";
import CustomEnvironment from "./custom-environment";
// Use custom environment class
const env = await helpers.createTestEnv(
(options) => new CustomEnvironment(options),
{
cwd: process.cwd(),
customFeature: true
}
);
// Register generators
env.register("./path/to/generator", { namespace: "my:gen" });
// Create generator instance
const generator = await env.create("my:gen", {
generatorArgs: ["init"],
generatorOptions: { force: true }
});import { create as createMemFs } from "mem-fs";
import helpers from "yeoman-test";
// Create shared file system
const sharedFs = createMemFs();
// Use with multiple environments
const env1 = await helpers.createTestEnv(undefined, {
sharedFs,
cwd: "/test/dir1"
});
const env2 = await helpers.createTestEnv(undefined, {
sharedFs,
cwd: "/test/dir2"
});
// Both environments share the same file systemconst env = await helpers.createTestEnv();
// Listen for environment events
env.on("compose", (namespace, generator) => {
console.log(`Composing with ${namespace}`);
});
env.on("error", (error) => {
console.error("Environment error:", error);
});
// Register and run generator
env.register("./my-generator", { namespace: "my:app" });
const generator = await env.create("my:app");
await env.runGenerator(generator);import helpers from "yeoman-test";
// Advanced prompt mocking
const adapter = helpers.createTestAdapter({
mockedAnswers: {
projectName: "my-project",
features: ["typescript", "testing"],
author: "Test Author"
},
throwOnMissingAnswer: true,
callback: (answer, { question }) => {
// Log all prompt interactions
console.log(`Question: ${question.message}`);
console.log(`Answer: ${answer}`);
// Modify answers based on question
if (question.name === "projectName") {
return answer.toLowerCase().replace(/\s+/g, "-");
}
return answer;
}
});
const env = await helpers.createTestEnv(undefined, { adapter });The test environment functionality integrates seamlessly with RunContext:
import helpers from "yeoman-test";
// Environment configuration flows through to RunContext
await helpers.run("my-generator", {
// RunContext settings
tmpdir: true,
namespace: "my:app"
}, {
// Environment options
localConfigOnly: false,
skipInstall: false,
force: true
});
// Custom environment constructor
const customEnvFactory = (options) => new CustomEnvironment(options);
await helpers.run("my-generator", {}, {
createEnv: customEnvFactory,
cwd: "/custom/path"
});describe("environment behavior", () => {
let env: DefaultEnvironmentApi;
beforeEach(async () => {
env = await helpers.createTestEnv({
localConfigOnly: true,
force: true
});
});
it("registers generators correctly", () => {
env.register("./path/to/generator", { namespace: "my:gen" });
const registered = env.getRegisteredPackages();
expect(registered).toHaveProperty("my:gen");
});
it("creates generators with options", async () => {
env.register("./my-generator", { namespace: "my:app" });
const generator = await env.create("my:app", {
generatorArgs: ["init", "--force"],
generatorOptions: { skipInstall: true }
});
expect(generator.options.skipInstall).toBe(true);
});
});Test environments created with createTestEnv include these defaults:
These defaults ensure consistent, isolated test execution while maintaining the flexibility to override any behavior when needed.
Install with Tessl CLI
npx tessl i tessl/npm-yeoman-test