---
name: generador-tests-automaticos
description: Genera tests unitarios, de integración y end-to-end para código existente, analizando funciones y dependencias. Soporta Jest, Vitest, Pytest, Playwright y Cypress con cobertura de casos de borde y mocks.
license: Apache-2.0
metadata:
  id: 4b41a482
  slug: generador-tests-automaticos
  titulo: "Generador de Tests Automáticos"
  servicio: Web
  categoria_recurso: Web-Desarrollo
  tipo: generacion
  nivel: intermedio
  idioma: es
  idioma_original: en
  acceso: gratis
  precio_eur: 0
  plataformas: [Node.js, Python, Jest, Vitest, Pytest, Playwright, Cypress, React Testing Library]
  dependencias: []
  licencia: { spdx: Apache-2.0, redistribuible: true, uso_comercial: true }
  fuente:
    repo: TerminalSkills/skills
    url: https://github.com/TerminalSkills/skills/tree/main/skills/test-generator
    commit: 77fa015
    autor: TerminalSkills
    nombre_original: test-generator
    duplicados_en: []
  seguridad: { veredicto: seguro, riesgo: bajo, escaneado: "2026-06-14", motor: "grep-estatico+auditor-llm" }
  ficha:
    que_hace: "Genera suites de tests completas (unitarios, integración y e2e) para código existente en proyectos JS/TS y Python."
    como_lo_hace: "Analiza el código fuente, detecta el framework de tests del proyecto y produce archivos de test con mocks, fixtures y casos de borde siguiendo las convenciones del proyecto."
  content_hash: "4b41a482893b2e4aaa0f421b552fbd661f8be75051895e3a97fc7340f69b29b1"
  version: 1.0.0
---

# Test Generator

## Overview

Automatically generate comprehensive tests for existing source code. This skill analyzes functions, classes, and modules to produce well-structured test suites with meaningful assertions, edge case coverage, and proper mocking. It supports multiple frameworks and test types (unit, integration, e2e).

## Instructions

When a user asks you to generate tests for their code, follow these steps:

### Step 1: Analyze the target code

Read the source file(s) and identify:
- **Functions/methods** to test, their signatures, parameters, and return types
- **Dependencies** that need mocking (database calls, API requests, file I/O)
- **Edge cases** — null inputs, empty arrays, boundary values, error paths
- **Side effects** — state mutations, event emissions, DOM changes

### Step 2: Detect the testing framework

Check the project for existing test setup:

```bash
# Check package.json for JS/TS projects
cat package.json | grep -E "jest|vitest|playwright|cypress|mocha|testing-library"

# Check for Python test frameworks
cat requirements.txt pyproject.toml setup.cfg 2>/dev/null | grep -E "pytest|unittest|hypothesis"

# Check for existing test config
ls jest.config* vitest.config* pytest.ini conftest.py .pytest.ini setup.cfg 2>/dev/null
```

If no framework is detected, recommend based on the project:
- **React/Next.js**: Vitest + React Testing Library
- **Node.js/Express**: Jest or Vitest
- **Python**: Pytest
- **E2E/browser**: Playwright

### Step 3: Generate the test file

Create tests following the framework conventions:

**Naming**: Place test files next to source files or in a `__tests__`/`tests` directory matching the project convention. Use `*.test.ts`, `*.spec.ts`, `test_*.py`, or `*_test.py`.

**Structure each test with:**
1. **Arrange** — set up inputs, mocks, and preconditions
2. **Act** — call the function or perform the action
3. **Assert** — verify the output, side effects, or state changes

**For each function, generate tests covering:**
- Happy path with typical inputs
- Edge cases (empty input, null, zero, max values)
- Error handling (invalid input, thrown exceptions)
- Boundary conditions

### Step 4: Set up mocks and fixtures

Mock external dependencies to isolate the unit under test:

**JavaScript/TypeScript (Jest/Vitest):**
```typescript
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { processOrder } from './order-service';
import { db } from './database';
import { sendEmail } from './email-service';

vi.mock('./database');
vi.mock('./email-service');

describe('processOrder', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should save the order and send confirmation email', async () => {
    const mockOrder = { id: 'ord_123', items: [{ sku: 'WIDGET-A', qty: 2 }], total: 49.98 };
    vi.mocked(db.orders.create).mockResolvedValue(mockOrder);
    vi.mocked(sendEmail).mockResolvedValue({ delivered: true });

    const result = await processOrder({ items: [{ sku: 'WIDGET-A', qty: 2 }] });

    expect(db.orders.create).toHaveBeenCalledOnce();
    expect(sendEmail).toHaveBeenCalledWith(expect.objectContaining({ orderId: 'ord_123' }));
    expect(result.id).toBe('ord_123');
  });
});
```

**Python (Pytest):**
```python
import pytest
from unittest.mock import patch, MagicMock
from order_service import process_order

@pytest.fixture
def mock_db():
    with patch('order_service.db') as mock:
        mock.orders.create.return_value = {"id": "ord_123", "total": 49.98}
        yield mock

def test_process_order_saves_and_sends_email(mock_db):
    result = process_order(items=[{"sku": "WIDGET-A", "qty": 2}])
    mock_db.orders.create.assert_called_once()
    assert result["id"] == "ord_123"

def test_process_order_rejects_empty_items():
    with pytest.raises(ValueError, match="at least one item"):
        process_order(items=[])
```

### Step 5: Add integration and e2e tests if requested

**Integration tests** — test multiple modules together with real (or test) databases:
- Use test containers or in-memory databases
- Test API routes end-to-end through the HTTP layer
- Verify database state after operations

**E2E tests (Playwright):**
```typescript
import { test, expect } from '@playwright/test';

test('user can add item to cart and checkout', async ({ page }) => {
  await page.goto('/products');
  await page.click('[data-testid="product-widget-a"]');
  await page.click('button:has-text("Add to Cart")');

  await page.goto('/cart');
  await expect(page.locator('.cart-item')).toHaveCount(1);
  await expect(page.locator('.cart-total')).toContainText('$24.99');

  await page.click('button:has-text("Checkout")');
  await expect(page).toHaveURL(/\/checkout/);
});
```

### Step 6: Verify and report coverage

Run the tests and report results:

```bash
# JavaScript
npx vitest run --coverage
# Python
pytest --cov=src --cov-report=term-missing
```

Report: total tests, pass/fail, and coverage percentage. Suggest additional tests if coverage is below 80%.

## Examples

### Example 1: Generate unit tests for a utility module

**User request:** "Write tests for src/utils/string-helpers.ts"

**Source code analyzed:**
```typescript
export function slugify(text: string): string {
  return text.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
}
export function truncate(text: string, maxLength: number): string {
  if (text.length <= maxLength) return text;
  return text.slice(0, maxLength - 3) + '...';
}
```

**Generated test file** (`src/utils/string-helpers.test.ts`):
```typescript
import { describe, it, expect } from 'vitest';
import { slugify, truncate } from './string-helpers';

describe('slugify', () => {
  it('converts spaces to hyphens', () => {
    expect(slugify('Hello World')).toBe('hello-world');
  });
  it('removes special characters', () => {
    expect(slugify('Price: $99.99!')).toBe('price-9999');
  });
  it('handles empty string', () => {
    expect(slugify('')).toBe('');
  });
  it('collapses multiple spaces', () => {
    expect(slugify('too   many   spaces')).toBe('too-many-spaces');
  });
});

describe('truncate', () => {
  it('returns original if within limit', () => {
    expect(truncate('short', 10)).toBe('short');
  });
  it('truncates and adds ellipsis', () => {
    expect(truncate('This is a very long sentence', 15)).toBe('This is a ve...');
  });
  it('handles exact length', () => {
    expect(truncate('exact', 5)).toBe('exact');
  });
});
```

**Result:** 7 tests generated, all passing. Coverage: 100% for `string-helpers.ts`.

### Example 2: Generate Pytest tests for a Flask API endpoint

**User request:** "Add tests for the /api/users endpoint in app.py"

**Source code analyzed:**
```python
@app.route('/api/users', methods=['POST'])
def create_user():
    data = request.get_json()
    if not data.get('email'):
        return jsonify({"error": "Email is required"}), 400
    user = User(email=data['email'], name=data.get('name', ''))
    db.session.add(user)
    db.session.commit()
    return jsonify({"id": user.id, "email": user.email}), 201
```

**Generated test file** (`tests/test_users_api.py`):
```python
import pytest
from app import app, db

@pytest.fixture
def client():
    app.config['TESTING'] = True
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
    with app.test_client() as client:
        with app.app_context():
            db.create_all()
        yield client

def test_create_user_success(client):
    response = client.post('/api/users', json={"email": "alice@example.com", "name": "Alice"})
    assert response.status_code == 201
    data = response.get_json()
    assert data["email"] == "alice@example.com"
    assert "id" in data

def test_create_user_missing_email(client):
    response = client.post('/api/users', json={"name": "Bob"})
    assert response.status_code == 400
    assert "Email is required" in response.get_json()["error"]

def test_create_user_empty_body(client):
    response = client.post('/api/users', json={})
    assert response.status_code == 400
```

**Result:** 3 tests generated, all passing. Covers success, validation error, and empty input.

## Guidelines

- Always match the existing test framework and style in the project. Do not introduce Jest if the project uses Vitest.
- Place test files following the project's existing convention (co-located vs. `tests/` directory).
- Use descriptive test names that explain the expected behavior, not the implementation.
- Mock external dependencies (databases, APIs, file system) but avoid over-mocking — test real logic.
- For each function, aim for at least: one happy path, one error case, one edge case.
- Generate `beforeEach`/`afterEach` setup when tests share common fixtures.
- Do not generate snapshot tests unless explicitly requested — they are brittle and rarely useful.
- When generating e2e tests, use stable selectors (`data-testid`) over CSS classes.
- If the project has no testing setup, install the framework and create the config file before writing tests.
- Report test count and coverage after generation so the user knows the current state.
