#!/bin/bash # Generate conftest.py boilerplate # Usage: ./generate-conftest.sh [--async] [--db] [--api] set -e OUTPUT="tests/conftest.py" # Check if tests directory exists if [[ ! -d "tests" ]]; then echo "Creating tests directory..." mkdir -p tests fi # Check if conftest.py already exists if [[ -f "$OUTPUT" ]]; then read -p "conftest.py already exists. Overwrite? [y/N] " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 0 fi fi # Parse arguments ASYNC="" DB="" API="" while [[ $# -gt 0 ]]; do case $1 in --async) ASYNC=1 shift ;; --db) DB=1 shift ;; --api) API=1 shift ;; *) shift ;; esac done # Generate conftest.py cat > "$OUTPUT" << 'HEADER' """ Pytest configuration and fixtures. Generated by generate-conftest.sh """ import pytest HEADER # Add async imports if needed if [[ -n "$ASYNC" ]]; then cat >> "$OUTPUT" << 'ASYNC_IMPORTS' import asyncio ASYNC_IMPORTS fi # Add database imports if needed if [[ -n "$DB" ]]; then cat >> "$OUTPUT" << 'DB_IMPORTS' from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker ASYNC_IMPORTS fi # Add API imports if needed if [[ -n "$API" ]]; then cat >> "$OUTPUT" << 'API_IMPORTS' from fastapi.testclient import TestClient # or: from flask.testing import FlaskClient ASYNC_IMPORTS fi # Add base fixtures cat >> "$OUTPUT" << 'BASE_FIXTURES' # ============================================================ # Test Configuration # ============================================================ def pytest_configure(config): """Register custom markers.""" config.addinivalue_line("markers", "slow: marks tests as slow") config.addinivalue_line("markers", "integration: marks integration tests") config.addinivalue_line("markers", "e2e: marks end-to-end tests") def pytest_collection_modifyitems(config, items): """Skip slow tests unless --slow flag is provided.""" if not config.getoption("--slow", default=False): skip_slow = pytest.mark.skip(reason="use --slow to run") for item in items: if "slow" in item.keywords: item.add_marker(skip_slow) def pytest_addoption(parser): """Add custom CLI options.""" parser.addoption( "--slow", action="store_true", default=False, help="run slow tests" ) # ============================================================ # Common Fixtures # ============================================================ @pytest.fixture def sample_data(): """Provide sample test data.""" return { "id": 1, "name": "Test", "active": True, } @pytest.fixture def temp_file(tmp_path): """Create a temporary file for testing.""" file_path = tmp_path / "test_file.txt" file_path.write_text("test content") return file_path BASE_FIXTURES # Add async fixtures if requested if [[ -n "$ASYNC" ]]; then cat >> "$OUTPUT" << 'ASYNC_FIXTURES' # ============================================================ # Async Fixtures # ============================================================ @pytest.fixture(scope="session") def event_loop(): """Create event loop for async tests.""" loop = asyncio.new_event_loop() yield loop loop.close() @pytest.fixture async def async_client(): """Async HTTP client fixture.""" import aiohttp async with aiohttp.ClientSession() as session: yield session ASYNC_FIXTURES fi # Add database fixtures if requested if [[ -n "$DB" ]]; then cat >> "$OUTPUT" << 'DB_FIXTURES' # ============================================================ # Database Fixtures # ============================================================ @pytest.fixture(scope="session") def db_engine(): """Create test database engine.""" engine = create_engine("sqlite:///:memory:") # Create tables here yield engine engine.dispose() @pytest.fixture def db_session(db_engine): """Create database session with transaction rollback.""" Session = sessionmaker(bind=db_engine) session = Session() yield session session.rollback() session.close() DB_FIXTURES fi # Add API fixtures if requested if [[ -n "$API" ]]; then cat >> "$OUTPUT" << 'API_FIXTURES' # ============================================================ # API Fixtures # ============================================================ @pytest.fixture def app(): """Create test application.""" from myapp import create_app app = create_app(testing=True) return app @pytest.fixture def client(app): """Create test client.""" return TestClient(app) @pytest.fixture def authenticated_client(client): """Create authenticated test client.""" # Add authentication logic here client.headers["Authorization"] = "Bearer test-token" return client API_FIXTURES fi echo "Generated $OUTPUT" echo "" echo "Options used:" [[ -n "$ASYNC" ]] && echo " --async: Async fixtures included" [[ -n "$DB" ]] && echo " --db: Database fixtures included" [[ -n "$API" ]] && echo " --api: API fixtures included"