mcpField
T
test-generator

test-generator

github.com/oimiragieoTesting & quality44122 installsUpdated 17w ago
Repository

About test-generator

A prompt-driven skill for generating tests from specifications and code while following a project's conventions. It is intended for developers who need unit, integration, API, or end-to-end tests, with checks for coverage and runnability.

Key features

  1. 01Generates tests to match project conventions
  2. 02Supports unit, integration, API, and E2E tests
  3. 03Analyzes edge cases and error scenarios
  4. 04Checks syntax, setup, and coverage

Use cases

  1. 01Add unit tests for new components or functions
  2. 02Create tests for API endpoints
  3. 03Write end-to-end tests for user flows
  4. 04Review test coverage in existing code

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/oimiragieo/agent-studio --skill test-generator

After installing, type/test-generatorin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

commands/
test-generator.md
hooks/
post-execute.cjs
pre-execute.cjs
references/
research-requirements.md
rules/
test-generator.md
schemas/
input.schema.json
output.schema.json
scripts/
main.cjs
templates/
implementation-template.md

Details

From the project README

Mode: Cognitive/Prompt-Driven — No standalone utility script; use via agent context.

Test Generator Skill - Generates test code from specifications, components, and API endpoints following project testing patterns and conventions. - Generating tests for new components - Creating tests for API endpoints - Generating E2E tests for user flows - Creating integration tests - Adding test coverage for existing code
Step 1: Identify Test Type

Determine what type of test is needed:

  • Unit Test: Component/function testing
  • Integration Test: Service/API integration
  • E2E Test: Full user flow testing
  • API Test: Endpoint testing
Step 2: Analyze Target Code

Examine code to test (Use Parallel Read/Grep/Glob):

  • Read component/function code
  • Identify test cases
  • Understand dependencies
  • Note edge cases
Step 3: Analyze Test Patterns

Review existing tests:

  • Read similar test files
  • Identify testing patterns
  • Note testing framework usage
  • Understand mocking strategies
Step 4: Generate Test Code

Create test following patterns:

  • Use appropriate testing framework
  • Follow project conventions
  • Include comprehensive coverage
  • Add edge cases and error scenarios
Step 5: Coverage Analysis

After generating tests, analyze coverage:

  1. Check that generated tests cover all requirements:

    • Verify all functions/methods are tested
    • Check all branches are covered (if/else, switch, etc.)
    • Ensure all edge cases are tested
    • Validate error scenarios are covered
  2. Validate tests are runnable:

    • Check test syntax is valid
    • Verify imports are correct
    • Ensure test framework is properly configured
    • Validate test setup/teardown is correct
  3. Report coverage percentage:

    • Calculate line coverage (if possible)
    • Calculate branch coverage (if possible)
    • Report uncovered code paths
    • Suggest additional tests for uncovered areas
  4. Coverage Validation Checklist:

    • All public functions/methods have tests
    • All error paths are tested
    • All edge cases are covered
    • Tests are syntactically valid
    • Tests can be executed successfully
    • Coverage meets project thresholds (if defined) </execution_process>
**Unit Test (React Component)**
import { render, screen, waitFor } from '@testing-library/react'
import { describe, it, expect, vi } from 'vitest'
import { UserProfile } from './user-profile'

describe('UserProfile', () => {
  it('renders user information', async () => {
    const mockUser = { id: '1', name: 'John', email: '[email protected]' }

    render(<UserProfile user={mockUser} />)

    await waitFor(() => {
      expect(screen.getByText('John')).toBeInTheDocument()
      expect(screen.getByText('[email protected]')).toBeInTheDocument()
    })
  })

  it('handles loading state', () => {
    render(<UserProfile user={null} loading />)
    expect(screen.getByTestId('loading')).toBeInTheDocument()
  })

  it('handles error state', () => {
    render(<UserProfile user={null} error="Failed to load" />)
    expect(screen.getByText('Failed to load')).toBeInTheDocument()
  })
})

</code_example>

<code_example> Integration Test (API)

import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { createTestClient } from './test-client';

describe('Users API', () => {
  let client: TestClient;

  beforeAll(() => {
    client = createTestClient();
  });

  afterAll(async () => {
    await client.cleanup();
  });

  it('creates a user', async () => {
    const response = await client.post('/api/users', {
      email: '[email protected]',
      name: 'Test User',
    });

    expect(response.status).toBe(201);
    expect(response.data).toHaveProperty('id');
    expect(response.data.email).toBe('[email protected]');
  });

  it('validates required fields', async () => {
    const response = await client.post('/api/users', {});

    expect(response.status).toBe(400);
    expect(response.data).toHaveProperty('errors');
  });
});

</code_example>

<code_example> E2E Test (Cypress)

describe('User Authentication Flow', () => {
  beforeEach(() => {
    cy.visit('/login');
  });

  it('allows user to login', () => {
    cy.get('[data-testid="email-input"]').type('[email protected]');
    cy.get('[data-testid="password-input"]').type('password123');
    cy.get('[data-testid="login-button"]').click();

    cy.url().should('include', '/dashboard');
    cy.get('[data-testid="user-menu"]').should('be.visible');
  });

  it('shows error for invalid credentials', () => {
    cy.get('[data-testid="email-input"]').type('[email protected]');
    cy.get('[data-testid="password-input"]').type('wrong');
    cy.get('[data-testid="login-button"]').click();

    cy.get('[data-testid="error-message"]')
      .should('be.visible')
      .and('contain', 'Invalid credentials');
  });
});

</code_example>

**Integration with Developer Agent**: - Generates tests during development - Ensures test coverage - Validates implementation

Integration with QA Agent:

  • Creates comprehensive test suites
  • Generates test plans
  • Validates test quality

<best_practices>

  1. Follow Patterns: Match existing test structure
  2. Comprehensive Coverage: Test happy paths and edge cases
  3. Clear Test Names: Descriptive test descriptions
  4. Isolate Tests: Each test should be independent
  5. Mock Dependencies: Use appropriate mocking strategies </best_practices>
**Example Commands**:
# Generate tests for a file
node .claude/skills/test-generator/scripts/main.cjs src/components/UserProfile.tsx

# The tool will analyze the file and generate appropriate tests

</usage_example>

Iron Laws

  1. ALWAYS analyze existing test patterns and framework conventions before generating any test code
  2. NEVER generate tests that inspect implementation details — test only public behavior and outputs
  3. ALWAYS include edge cases: null/undefined inputs, boundary values, and error scenarios for every tested unit
  4. NEVER produce tests with shared mutable state — use beforeEach/afterEach to isolate every test
  5. ALWAYS verify generated tests are syntactically valid and runnable before marking generation complete

Anti-Patterns

Anti-PatternWhy It FailsCorrect Approach
Testing implementation detailsBreaks on refactor even when behavior is unchangedTest public API behavior and observable outputs
No assertions in test bodyTest always passes, catches nothingAdd explicit assertions for every test case
Shared mutable state between testsTests fail depending on execution orderUse beforeEach/afterEach for full isolation
Magic numbers in assertionsUnclear expected values, brittle testsUse named constants or descriptive fixture data
Missing error path testsHalf coverage, silent failures in productionTest both success and failure scenarios

Memory Protocol (MANDATORY)

Before starting: Read .claude/context/memory/learnings.md

After completing:

  • New pattern -> .claude/context/memory/learnings.md
  • Issue found -> .claude/context/memory/issues.md
  • Decision made -> .claude/context/memory/decisions.md

ASSUME INTERRUPTION: If it's not in memory, it didn't happen.

Comments

Markdown supported