paper-dynasty-gameplay-webapp/tests/README.md
Cal Corum c09f9d1302 CLAUDE: Initialize Paper Dynasty web app with Model/Service Architecture
Establishes foundation for migrating baseball simulation from Discord bot to web application using service-oriented architecture pattern.

Key components:
- FastAPI application structure with dependency injection
- Service layer foundation with base classes and container
- Comprehensive directory documentation with README files
- PostgreSQL containerization with Docker Compose
- Testing structure for unit/integration/e2e tests
- Migration planning documentation
- Rotating log configuration per user requirements

Architecture follows Model/Service/Controller pattern to improve testability, maintainability, and scalability over original monolithic Discord app.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-27 21:44:12 -05:00

5.3 KiB

Tests Directory

This directory contains the comprehensive test suite for the Paper Dynasty web app, organized by testing scope and purpose following the Model/Service Architecture.

Testing Strategy

Test Pyramid Structure

  • Unit Tests (80%+ coverage): Fast, isolated tests for services and engine
  • Integration Tests (70%+ coverage): Service + database interactions
  • End-to-End Tests (Happy path): Complete user workflows

Testing Priorities

  1. Services: Core business logic with mocked dependencies
  2. Engine: Stateless game simulation functions
  3. Integration: Service interactions with real database
  4. Routes: HTTP handling with mocked services

Directory Structure

tests/
├── unit/                   # Fast, isolated unit tests
│   ├── services/           # Service unit tests (MOST IMPORTANT)
│   ├── engine/             # Engine unit tests
│   └── models/             # Model validation tests
├── integration/            # Service + database integration
└── e2e/                   # Full application tests

Unit Tests (unit/)

Services (unit/services/)

Critical for Model/Service Architecture

Tests business logic independently of database and web framework:

# test_game_service.py
@pytest.fixture
def mock_session():
    return Mock(spec=Session)

@pytest.fixture
def game_service(mock_session):
    return GameService(mock_session)

@pytest.mark.asyncio
async def test_create_game_validates_teams(game_service):
    # Test business logic without database
    with pytest.raises(ValidationError):
        await game_service.create_game(999, 1000)  # Invalid teams

Engine (unit/engine/)

Tests stateless game simulation functions:

# test_dice.py
def test_dice_probability_distribution():
    # Test dice rolling mechanics
    results = [roll_dice() for _ in range(1000)]
    assert 1 <= min(results) <= max(results) <= 6

# test_simulation.py
def test_pitcher_vs_batter_mechanics():
    # Test core game simulation
    result = simulate_at_bat(pitcher_stats, batter_stats)
    assert result.outcome in ['hit', 'out', 'walk', 'strikeout']

Models (unit/models/)

Tests data validation and relationships:

# test_models.py
def test_game_model_validation():
    # Test SQLModel validation
    with pytest.raises(ValidationError):
        Game(away_team_id=None)  # Required field

Integration Tests (integration/)

Tests service interactions with real database (isolated transactions):

# test_game_flow.py
@pytest.mark.asyncio
async def test_complete_game_creation_flow(db_session):
    game_service = GameService(db_session)

    # Create test data
    team1 = await create_test_team(db_session)
    team2 = await create_test_team(db_session)

    # Test full flow with real database
    game = await game_service.create_game(team1.id, team2.id)

    assert game.id is not None
    assert game.away_team_id == team1.id

End-to-End Tests (e2e/)

Tests complete user journeys through web interface:

# test_game_creation.py
def test_user_can_create_game(client):
    # Test complete user workflow
    response = client.post("/auth/login")  # Login
    response = client.post("/games/start", json={...})  # Create game
    response = client.get(f"/game/{game_id}")  # View game

    assert "Game created successfully" in response.text

Running Tests

All Tests

pytest

Specific Test Types

# Unit tests only (fast)
pytest tests/unit/

# Integration tests only
pytest tests/integration/

# End-to-end tests only
pytest tests/e2e/

# Specific service tests
pytest tests/unit/services/test_game_service.py

# Single test function
pytest tests/unit/services/test_game_service.py::test_create_game_success

With Coverage

# Coverage report
pytest --cov=app

# Coverage with HTML report
pytest --cov=app --cov-report=html

Test Configuration

Fixtures

Common test fixtures for database, services, and test data:

# conftest.py
@pytest.fixture
def db_session():
    # Isolated database session for integration tests
    pass

@pytest.fixture
def mock_game_service():
    # Mocked service for route testing
    pass

@pytest.fixture
def test_game_data():
    # Sample game data for tests
    pass

Test Database

Integration tests use a separate test database:

  • DATABASE_TEST_URL environment variable
  • Isolated transactions (rollback after each test)
  • Clean state for each test

Testing Best Practices

Service Testing

  • Mock database sessions for unit tests
  • Test business logic independently of framework
  • Validate error handling and edge cases
  • Test service interactions with integration tests

Test Data Management

  • Use factories for creating test data
  • Isolate test state (no shared mutable state)
  • Clean up after tests (database rollback)

Coverage Goals

  • Services: 90%+ coverage (core business logic)
  • Engine: 95%+ coverage (critical game mechanics)
  • Routes: 80%+ coverage (HTTP handling)
  • Models: 85%+ coverage (data validation)

Migration Testing

When migrating from Discord app:

  1. Extract and test business logic in service unit tests
  2. Validate game mechanics with engine tests
  3. Test service integration with database
  4. Ensure web interface works with e2e tests