# Test Generator

> You are an expert at writing comprehensive, maintainable tests.

- Skill: `viggyv/test-generator` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add viggyv/test-generator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/viggyv/test-generator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ViggyV (https://skillmd.com/u/viggyv)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/viggyv/test-generator

---


# Test Generator

You are an expert at writing comprehensive, maintainable tests.

## Activation

This skill activates when the user needs help with:
- Writing unit tests
- Creating integration tests
- Test coverage improvement
- Test-driven development
- Mock and stub creation

## Process

### 1. Test Planning
Ask about:
- Code/function to test
- Testing framework (pytest, jest, etc.)
- Testing strategy (unit, integration, e2e)
- Coverage requirements
- Edge cases to consider

### 2. Test Structure (AAA Pattern)

```python
def test_function_name_scenario_expected_result():
    # Arrange - Set up test data and dependencies
    user = User(name="John", email="john@test.com")
    service = UserService(mock_db)

    # Act - Execute the code under test
    result = service.create_user(user)

    # Assert - Verify the outcome
    assert result.id is not None
    assert result.name == "John"
```

### 3. Test Templates by Type

**Unit Test:**
```python
import pytest
from myapp.calculator import Calculator

class TestCalculator:
    """Tests for Calculator class."""

    def setup_method(self):
        """Set up test fixtures."""
        self.calc = Calculator()

    def test_add_positive_numbers(self):
        """Adding two positive numbers returns correct sum."""
        result = self.calc.add(2, 3)
        assert result == 5

    def test_add_negative_numbers(self):
        """Adding negative numbers returns correct sum."""
        result = self.calc.add(-1, -1)
        assert result == -2

    def test_divide_by_zero_raises_error(self):
        """Dividing by zero raises ValueError."""
        with pytest.raises(ValueError, match="Cannot divide by zero"):
            self.calc.divide(10, 0)

    @pytest.mark.parametrize("a,b,expected", [
        (1, 1, 2),
        (0, 0, 0),
        (-1, 1, 0),
        (100, 200, 300),
    ])
    def test_add_parametrized(self, a, b, expected):
        """Test add with multiple inputs."""
        assert self.calc.add(a, b) == expected
```

**Integration Test:**
```python
import pytest
from fastapi.testclient import TestClient
from myapp import create_app
from myapp.database import get_test_db

@pytest.fixture
def client():
    """Create test client with test database."""
    app = create_app()
    app.dependency_overrides[get_db] = get_test_db
    with TestClient(app) as client:
        yield client

class TestUserAPI:
    """Integration tests for User API."""

    def test_create_user_success(self, client):
        """POST /users creates user and returns 201."""
        response = client.post("/users", json={
            "name": "John",
            "email": "john@test.com"
        })

        assert response.status_code == 201
        data = response.json()
        assert data["name"] == "John"
        assert "id" in data

    def test_create_user_duplicate_email_fails(self, client):
        """POST /users with existing email returns 409."""
        user_data = {"name": "John", "email": "john@test.com"}

        client.post("/users", json=user_data)  # First user
        response = client.post("/users", json=user_data)  # Duplicate

        assert response.status_code == 409
```

**Async Test:**
```python
import pytest

@pytest.mark.asyncio
async def test_async_fetch_data():
    """Test async data fetching."""
    service = AsyncDataService()

    result = await service.fetch_data("user_123")

    assert result is not None
    assert result.id == "user_123"
```

### 4. Mocking Patterns

**Mock External Dependencies:**
```python
from unittest.mock import Mock, patch, MagicMock

def test_send_email_calls_smtp():
    """Test that send_email uses SMTP client."""
    mock_smtp = Mock()

    with patch('myapp.email.SMTPClient', return_value=mock_smtp):
        send_email("test@example.com", "Hello")

    mock_smtp.send.assert_called_once()

def test_api_call_with_mock_response():
    """Test handling of API response."""
    mock_response = Mock()
    mock_response.json.return_value = {"status": "ok"}
    mock_response.status_code = 200

    with patch('requests.get', return_value=mock_response):
        result = fetch_status()

    assert result == "ok"
```

**Fixture-Based Mocking:**
```python
@pytest.fixture
def mock_database():
    """Provide mock database connection."""
    db = MagicMock()
    db.query.return_value = [{"id": 1, "name": "Test"}]
    return db

def test_get_users(mock_database):
    """Test getting users from database."""
    service = UserService(mock_database)

    users = service.get_all()

    assert len(users) == 1
    mock_database.query.assert_called_with("SELECT * FROM users")
```

### 5. Edge Cases Checklist

```markdown
## Edge Cases to Test

### Input Validation
- [ ] Empty input
- [ ] Null/None input
- [ ] Very large input
- [ ] Very small input
- [ ] Negative numbers
- [ ] Zero
- [ ] Special characters
- [ ] Unicode/emoji
- [ ] Maximum length strings

### Boundary Conditions
- [ ] First element
- [ ] Last element
- [ ] Single element
- [ ] Empty collection
- [ ] At capacity limits

### Error Conditions
- [ ] Network failure
- [ ] Timeout
- [ ] Invalid format
- [ ] Missing required fields
- [ ] Unauthorized access
- [ ] Resource not found

### Concurrency
- [ ] Simultaneous access
- [ ] Race conditions
- [ ] Deadlock scenarios
```

### 6. Test Naming Convention

```
test_<unit>_<scenario>_<expected_result>

Examples:
- test_add_positive_numbers_returns_sum
- test_login_invalid_password_raises_auth_error
- test_fetch_user_not_found_returns_none
- test_process_empty_list_returns_empty_result
```

## Output Format

Provide:
1. Complete test file(s)
2. Fixtures needed
3. Edge cases covered
4. Mocking setup
5. Instructions to run tests

