@specsafe/test-gen
Test generation library for the SpecSafe spec-driven development framework. Parses specifications and generates TypeScript test files.
Installation
npm install @specsafe/test-gen
What It Provides
- ScenarioParser - Parse requirement scenarios from spec files
- TypeScriptTestGenerator - Generate TypeScript test files from parsed requirements
- Framework Support - Vitest (default) and Jest
API Reference
ScenarioParser
Parses specification files and extracts requirements.
import { ScenarioParser } from '@specsafe/test-gen';
const parser = new ScenarioParser();
parseRequirements(specContent: string): Requirement[]
Parse requirements from spec content.
const specContent = `
## Requirements
### REQ-001: User Login
**Given** a registered user with email "user@example.com"
**When** they enter the correct password
**Then** they should be redirected to the dashboard
### REQ-002: Invalid Password
**Given** a registered user
**When** they enter an incorrect password
**Then** an error message should be displayed
`;
const requirements = parser.parseRequirements(specContent);
console.log(requirements);
TypeScriptTestGenerator
Generates TypeScript test files from requirements.
import { TypeScriptTestGenerator } from '@specsafe/test-gen';
const generator = new TypeScriptTestGenerator({
framework: 'vitest',
specId: 'user-authentication'
});
generate(requirements: Requirement[]): string
Generate test file content.
const requirements = [
{
id: 'REQ-001',
title: 'User Login',
given: 'a registered user',
when: 'they enter valid credentials',
then: 'they should be logged in'
}
];
const testCode = generator.generate(requirements);
console.log(testCode);
Framework Support
Vitest (Default)
const generator = new TypeScriptTestGenerator({
framework: 'vitest',
specId: 'my-feature'
});
Generates tests using Vitest's describe, it, and expect:
import { describe, it, expect } from 'vitest';
describe('My Feature', () => {
it('REQ-001: Requirement Title', () => {
});
});
Jest
const generator = new TypeScriptTestGenerator({
framework: 'jest',
specId: 'my-feature'
});
Generates tests using Jest's globals:
describe('My Feature', () => {
it('REQ-001: Requirement Title', () => {
});
});
Usage Examples
Basic Usage
import { ScenarioParser, TypeScriptTestGenerator } from '@specsafe/test-gen';
import { readFileSync, writeFileSync } from 'fs';
const specContent = readFileSync('./specs/active/login.spec.md', 'utf-8');
const parser = new ScenarioParser();
const requirements = parser.parseRequirements(specContent);
const generator = new TypeScriptTestGenerator({
framework: 'vitest',
specId: 'login'
});
const testCode = generator.generate(requirements);
writeFileSync('./src/specs/login.spec.ts', testCode);
Custom Test Body
The generated tests include comments based on the Gherkin-style requirements:
You fill in the actual test implementation:
it('REQ-001: User Login', () => {
const user = createUser({ email: 'test@example.com', password: 'secret' });
const result = login(user.email, user.password);
expect(result.authenticated).toBe(true);
});
Processing Multiple Specs
import { ScenarioParser, TypeScriptTestGenerator } from '@specsafe/test-gen';
import { readdirSync, readFileSync, writeFileSync } from 'fs';
import { join } from 'path';
const parser = new ScenarioParser();
const specsDir = './specs/active';
const outputDir = './src/specs';
const specFiles = readdirSync(specsDir).filter(f => f.endsWith('.spec.md'));
for (const file of specFiles) {
const specId = file.replace('.spec.md', '');
const content = readFileSync(join(specsDir, file), 'utf-8');
const requirements = parser.parseRequirements(content);
const generator = new TypeScriptTestGenerator({
framework: 'vitest',
specId
});
const testCode = generator.generate(requirements);
writeFileSync(join(outputDir, `${specId}.spec.ts`), testCode);
console.log(`Generated tests for ${specId}`);
}
Specification Format
Requirements should follow this format in your spec files:
## Requirements
### REQ-XXX: Requirement Title
**Given** [context]
**When** [action]
**Then** [expected result]
Where:
REQ-XXX is a unique requirement ID (e.g., REQ-001, REQ-002)
- Given describes the initial context/state
- When describes the action taken
- Then describes the expected outcome
License
MIT © Agentic Engineering