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>
206 lines
5.3 KiB
Markdown
206 lines
5.3 KiB
Markdown
# 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:
|
|
|
|
```python
|
|
# 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:
|
|
|
|
```python
|
|
# 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:
|
|
|
|
```python
|
|
# 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):
|
|
|
|
```python
|
|
# 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:
|
|
|
|
```python
|
|
# 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
|
|
```bash
|
|
pytest
|
|
```
|
|
|
|
### Specific Test Types
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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:
|
|
|
|
```python
|
|
# 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 |