Claude
Skills
Sign in
Back

pytest-fixture-generator

Included with Lifetime
$97 forever

Generate standardized pytest configuration with fixtures, markers, and coverage settings. Creates conftest.py and pytest.ini for workspace-hub compliant testing.

workspace-hub

What this skill does


# Pytest Fixture Generator

> Generate standardized pytest configuration compliant with workspace-hub testing standards.

## Quick Start

```bash
# Generate pytest configuration
/pytest-fixture-generator

# Generate with specific markers
/pytest-fixture-generator --markers unit,integration,slow

# Generate for specific module structure
/pytest-fixture-generator --src-path src/modules
```

## When to Use

**USE when:**
- Setting up new Python project testing
- Standardizing existing test configuration
- Adding fixtures for data processing projects
- Configuring coverage requirements

**DON'T USE when:**
- Non-Python projects
- Tests already fully configured
- Different testing framework needed

## Prerequisites

- Python 3.9+
- pytest>=7.4.0
- pytest-cov>=4.1.0
- Project with src/ structure

## Overview

Generates complete pytest configuration including:

1. **pytest.ini** - pytest configuration with markers
2. **conftest.py** - Shared fixtures and path setup
3. **Coverage config** - .coveragerc or pyproject.toml
4. **Test templates** - Example test files

## Generated Files

### pytest.ini

```ini
[pytest]
testpaths = tests
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_*

# Markers for test categorization
markers =
    unit: Unit tests (fast, isolated)
    integration: Integration tests (may use external resources)
    slow: Slow running tests (> 1 second)
    llm: Tests requiring LLM API (may be skipped in CI)
    scrapy: Web scraping tests
    selenium: Browser automation tests
    database: Database interaction tests
    api: External API tests
    etl: ETL pipeline tests

# Default options
addopts =
    -v
    --strict-markers
    --tb=short
    --cov=src
    --cov-report=term-missing
    --cov-fail-under=80

# Async support
asyncio_mode = auto

# Timeout for tests
timeout = 300

# Filter warnings
filterwarnings =
    ignore::DeprecationWarning
    ignore::PendingDeprecationWarning
```

### conftest.py

```python
"""
ABOUTME: Pytest configuration and shared fixtures for testing
ABOUTME: Provides path setup, common fixtures, and test utilities
"""

import sys
from pathlib import Path
from typing import Any, Dict, Generator
import pytest
import logging

# ============================================================================
# Path Configuration
# ============================================================================

# Get project root
PROJECT_ROOT = Path(__file__).parent.parent
SRC_PATH = PROJECT_ROOT / "src"
MODULES_PATH = SRC_PATH / "modules"

# Add paths to sys.path for imports (deduplicated)
paths_to_add = [str(SRC_PATH), str(MODULES_PATH)]
for path in paths_to_add:
    if path not in sys.path:
        sys.path.insert(0, path)


# ============================================================================
# Platform-specific Skipping
# ============================================================================

def is_windows() -> bool:
    """Check if running on Windows."""
    return sys.platform.startswith('win')


def is_orcaflex_available() -> bool:
    """Check if OrcaFlex is available."""
    try:
        import OrcFxAPI
        return True
    except ImportError:
        return False


# Skip markers
skip_if_not_windows = pytest.mark.skipif(
    not is_windows(),
    reason="Windows-only test"
)

skip_if_no_orcaflex = pytest.mark.skipif(
    not is_orcaflex_available(),
    reason="OrcaFlex not available"
)


# ============================================================================
# Logging Configuration
# ============================================================================

@pytest.fixture(scope="session")
def configure_logging():
    """Configure logging for test session."""
    logging.basicConfig(
        level=logging.DEBUG,
        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    return logging.getLogger("test")


# ============================================================================
# Path Fixtures
# ============================================================================

@pytest.fixture(scope="session")
def project_root() -> Path:
    """Return project root directory."""
    return PROJECT_ROOT


@pytest.fixture(scope="session")
def data_dir(project_root) -> Path:
    """Return data directory path."""
    return project_root / "data"


@pytest.fixture(scope="session")
def raw_data_dir(data_dir) -> Path:
    """Return raw data directory path."""
    return data_dir / "raw"


@pytest.fixture(scope="session")
def test_data_dir() -> Path:
    """Return test fixtures directory."""
    return Path(__file__).parent / "fixtures"


@pytest.fixture
def temp_output_dir(tmp_path) -> Path:
    """Return temporary output directory for test."""
    output_dir = tmp_path / "output"
    output_dir.mkdir(exist_ok=True)
    return output_dir


# ============================================================================
# Sample Data Fixtures
# ============================================================================

@pytest.fixture
def sample_dict() -> Dict[str, Any]:
    """Provide sample dictionary data."""
    return {
        "name": "test_item",
        "value": 42,
        "enabled": True,
        "items": [1, 2, 3, 4, 5],
        "metadata": {
            "created": "2026-01-14",
            "author": "tester"
        }
    }


@pytest.fixture
def sample_list() -> list:
    """Provide sample list data."""
    return [
        {"id": 1, "value": 10},
        {"id": 2, "value": 20},
        {"id": 3, "value": 30},
    ]


@pytest.fixture
def sample_dataframe():
    """Provide sample pandas DataFrame."""
    import pandas as pd
    return pd.DataFrame({
        "id": [1, 2, 3, 4, 5],
        "name": ["a", "b", "c", "d", "e"],
        "value": [10.0, 20.0, 30.0, 40.0, 50.0],
        "category": ["x", "y", "x", "y", "x"]
    })


@pytest.fixture
def sample_time_series():
    """Provide sample time series DataFrame."""
    import pandas as pd
    import numpy as np

    dates = pd.date_range("2026-01-01", periods=100, freq="D")
    return pd.DataFrame({
        "date": dates,
        "value": np.random.randn(100).cumsum() + 100,
        "volume": np.random.randint(100, 1000, 100)
    })


# ============================================================================
# Configuration Fixtures
# ============================================================================

@pytest.fixture
def temp_config(tmp_path) -> Path:
    """Create temporary YAML configuration file."""
    config_file = tmp_path / "config.yaml"
    config_file.write_text("""
metadata:
  name: test-config
  version: 1.0.0

settings:
  debug: true
  log_level: DEBUG
  output_dir: ./output

input:
  source: data/input.csv
  encoding: utf-8

output:
  format: html
  path: reports/output.html
""")
    return config_file


@pytest.fixture
def temp_csv(tmp_path, sample_dataframe) -> Path:
    """Create temporary CSV file with sample data."""
    csv_path = tmp_path / "test_data.csv"
    sample_dataframe.to_csv(csv_path, index=False)
    return csv_path


# ============================================================================
# Mock Fixtures
# ============================================================================

@pytest.fixture
def mock_api_response() -> Dict[str, Any]:
    """Provide mock API response."""
    return {
        "status": "success",
        "data": [
            {"id": 1, "result": "ok"},
            {"id": 2, "result": "ok"},
        ],
        "metadata": {
            "total": 2,
            "page": 1
        }
    }


@pytest.fixture
def mock_error_response() -> Dict[str, Any]:
    """Provide mock error response."""
    return {
        "status": "error",
        "error": {
            "code": "INVALID_INPUT",
            "message": "Input validation failed"
        }
    }


# ============================================================================
# Cleanup Fixtures
# =======================================================================

Related in workspace-hub