generateTest
Create automated tests for frontend code using Jest or Cypress frameworks. Supports unit, component, and end-to-end testing in JavaScript, TypeScript, JSX, and TSX.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ||
| description | No | ||
| framework | Yes | ||
| language | No | javascript | |
| type | Yes |
Implementation Reference
- src/tools/generator.ts:15-33 (handler)Handler function for the 'generateTest' tool. It calls the generateTestCode helper with provided parameters and returns the generated test code in MCP format, or an error if generation fails.async ({ code, framework, type, language, description }) => { try { const testCode = generateTestCode(code, framework, type, language, description); return { content: [{ type: 'text', text: testCode, }], }; } catch (error) { return { isError: true, content: [{ type: 'text', text: `Error generating test: ${String(error)}`, }], }; } }
- src/tools/generator.ts:8-14 (schema)Input schema for the 'generateTest' tool using Zod, validating code snippet, testing framework, test type, language, and optional description.{ code: z.string(), framework: z.enum(['jest', 'cypress']), type: z.enum(['unit', 'component', 'e2e']), language: z.enum(['javascript', 'typescript', 'jsx', 'tsx']).default('javascript'), description: z.string().optional() },
- src/tools/generator.ts:6-34 (registration)The server.tool call that registers the 'generateTest' tool, including its schema and handler implementation.server.tool( 'generateTest', { code: z.string(), framework: z.enum(['jest', 'cypress']), type: z.enum(['unit', 'component', 'e2e']), language: z.enum(['javascript', 'typescript', 'jsx', 'tsx']).default('javascript'), description: z.string().optional() }, async ({ code, framework, type, language, description }) => { try { const testCode = generateTestCode(code, framework, type, language, description); return { content: [{ type: 'text', text: testCode, }], }; } catch (error) { return { isError: true, content: [{ type: 'text', text: `Error generating test: ${String(error)}`, }], }; } } );
- src/tools/generator.ts:39-182 (helper)Primary helper function that implements the test generation logic. Analyzes source code, extracts name, generates imports and test suites tailored to framework (Jest/Cypress) and type (unit/component/e2e), incorporating analysis results.export function generateTestCode( sourceCode: string, framework: string, testType: string, language: string, description?: string ): string { // Analyze the code to better understand its structure const analysis = performCodeAnalysis(sourceCode, language); // Extract component or function name const nameMatch = sourceCode.match(/(?:function|class|const)\s+(\w+)/); const name = nameMatch ? nameMatch[1] : 'Component'; // Generate appropriate import statements based on framework and test type let imports = ''; let testCode = ''; if (framework === 'jest') { if (testType === 'unit') { imports = `// Import the module to test\n${language.includes('typescript') ? `import { ${name} } from './${name}';` : `const ${name} = require('./${name}');`}`; testCode = `describe('${name}', () => { test('${description || 'should work correctly'}', () => { // Arrange ${(analysis as any)?.codeType?.isFunction ? ` // Example test input const input = 'test'; // Act const result = ${name}(input); // Assert expect(result).toBeDefined();` : ` // Setup any required state // Act - perform the action // Assert - check the result expect(true).toBe(true);`} }); ${(analysis as any)?.complexity?.hasAsync ? ` test('handles async operations', async () => { // Arrange // Act const result = await ${name}(); // Assert expect(result).toBeDefined(); });` : ''} });`; } else if (testType === 'component') { imports = `import { render, screen${(analysis as any)?.complexity?.hasEvents ? ', fireEvent' : ''} } from '@testing-library/react';\n${(analysis as any)?.complexity?.hasEvents ? `import userEvent from '@testing-library/user-event';` : ''}\n${language.includes('typescript') ? `import { ${name} } from './${name}';` : `import { default as ${name} } from './${name}';`}`; testCode = `describe('${name}', () => { test('renders correctly', () => { // Arrange render(<${name} />); // Assert expect(screen.getByText(/content/i)).toBeInTheDocument(); }); ${(analysis as any).complexity?.hasEvents ? ` test('handles user interaction', async () => { // Arrange render(<${name} />); // Act await userEvent.click(screen.getByRole('button')); // Assert expect(screen.getByText(/result/i)).toBeInTheDocument(); });` : ''} ${(analysis as any)?.complexity?.hasAsync ? ` test('loads data asynchronously', async () => { // Arrange render(<${name} />); // Act - wait for async operation await screen.findByText(/loaded/i); // Assert expect(screen.getByText(/loaded/i)).toBeInTheDocument(); });` : ''} });`; } } else if (framework === 'cypress') { if (testType === 'component') { imports = `${language.includes('typescript') ? `import { ${name} } from './${name}';` : `import Component from './Component';`}`; testCode = `describe('${name}', () => { it('renders correctly', () => { // Arrange cy.mount(<${name} />); // Assert cy.contains(/content/i).should('be.visible'); }); ${(analysis as any)?.complexity?.hasEvents ? ` it('handles user interaction', () => { // Arrange cy.mount(<${name} />); // Act cy.get('button').click(); // Assert cy.contains(/result/i).should('be.visible'); });` : ''} ${(analysis as any)?.complexity?.hasAsync ? ` it('loads data asynchronously', () => { // Arrange cy.mount(<${name} />); // Assert - wait for async operation cy.contains(/loaded/i, { timeout: 10000 }).should('be.visible'); });` : ''} });`; } else if (testType === 'e2e') { imports = '// No imports needed for Cypress E2E tests'; testCode = `describe('${name} E2E Test', () => { beforeEach(() => { // Visit the page containing the component cy.visit('/'); }); it('${description || 'works correctly'}', () => { // Assert the component is rendered cy.contains(/content/i).should('be.visible'); ${(analysis as any)?.complexity?.hasEvents ? ` // Act - interact with the component cy.get('button').click(); // Assert the interaction worked cy.contains(/result/i).should('be.visible');` : ''} ${(analysis as any)?.complexity?.hasAsync ? ` // Assert async data loads correctly cy.contains(/loaded/i, { timeout: 10000 }).should('be.visible');` : ''} }); });`; } } // Combine imports and test code return `${imports}\n${testCode}`; }
- src/tools/analyzer.ts:36-128 (helper)Supporting helper function called by generateTestCode to statically analyze the source code, detecting React components, functions, hooks, events, async operations, and providing test recommendations.export function performCodeAnalysis(code: string, language: string): any { const analysisResult: any = { codeType: {}, complexity: {}, recommendations: {} }; try { // Determine if the code is a React component const isReactComponent = code.includes('import React') || code.includes('from "react"') || code.includes("from 'react'") || code.includes('extends Component') || code.includes('React.Component') || ((code.includes('export') && code.includes('return')) && (code.includes('JSX.') || code.includes('<div') || code.includes('<>'))); // Check if it's a function or class const isClass = code.includes('class ') && code.includes('extends '); const isFunction = code.includes('function ') || code.includes('=>'); // Check if it uses hooks const usesHooks = code.includes('useState') || code.includes('useEffect') || code.includes('useContext') || code.includes('useReducer') || code.includes('useCallback') || code.includes('useMemo'); // Count imports to determine complexity const importMatches = code.match(/import .+ from .+/g); const imports = importMatches ? importMatches.length : 0; // Look for event handlers const hasEvents = code.includes('onClick') || code.includes('onChange') || code.includes('onSubmit') || code.includes('addEventListener'); // Look for async operations const hasAsync = code.includes('async ') || code.includes('await ') || code.includes('Promise') || code.includes('.then(') || code.includes('fetch('); const recommendedTestTypes: string[] = []; if (isReactComponent) { recommendedTestTypes.push('component'); if (hasEvents || hasAsync) { recommendedTestTypes.push('e2e'); } else { recommendedTestTypes.push('unit'); } } else { recommendedTestTypes.push('unit'); } // Recommend testing frameworks const recommendedFrameworks: string[] = []; if (isReactComponent) { recommendedFrameworks.push('jest'); if (hasEvents) { recommendedFrameworks.push('cypress'); } else { recommendedFrameworks.push('jest'); } } else { recommendedFrameworks.push('jest'); } analysisResult.codeType = { isReactComponent, isClass, isFunction, usesHooks, }; analysisResult.complexity = { imports, hasEvents, hasAsync }; analysisResult.recommendations = { testTypes: recommendedTestTypes, frameworks: recommendedFrameworks, priority: hasAsync ? 'high' : 'medium' }; } catch (error: any) { console.error(`Error during code analysis: ${error.message}`); } return analysisResult; }