Make sure Docker Compose is running:
docker compose upThe test database (studyclever_test) is created automatically on first run. If it doesn't exist:
docker compose exec postgres psql -U postgres -c "CREATE DATABASE studyclever_test;"docker compose exec backend pytest tests/ -vdocker compose exec backend pytest tests/test_schedule_generator.py -v
docker compose exec backend pytest tests/test_queue_service.py -v
docker compose exec backend pytest tests/test_auth.py -vdocker compose exec backend pytest tests/test_schedule_generator.py::TestEasingInDistribution -vdocker compose exec backend pytest tests/test_schedule_generator.py::TestEasingInDistribution::test_sum_matches_total -vdocker compose exec backend pytest tests/ -v --tb=shortdocker compose exec backend pytest tests/ --lfbackend/tests/
├── test_auth.py # Registration, login, JWT
├── test_modules.py # Module + lecture CRUD
├── test_schedule_config.py # Schedule config validation
├── test_schedule_generator.py # Distribution algorithms, two-phase, progress
├── test_queue_service.py # Daily queue, answers, timers, study ahead
├── test_familiarization.py # One-per-slide selection, skip handling
├── test_progress.py # Progress tracking, streaks
├── test_flags.py # Question flagging
├── test_regeneration.py # Deck system, fam survival
├── test_enrichment.py # Enrichment service (existing)
├── test_batch_manager.py # Batch manager (existing)
├── test_e2e_flow.py # Full end-to-end happy path
└── __init__.py
Available fixtures in all test files:
| Fixture | Description |
|---|---|
db |
Transactional database session (rolls back after each test) |
client |
FastAPI TestClient with test DB |
test_user |
A registered user |
auth_headers |
JWT auth headers for test_user |
test_module |
Module with future exam date |
test_lectures |
3 lectures with 5 slides each |
test_questions |
4 questions per slide (60 total) |
test_schedule_config |
Default schedule config |
- Create a new file in
backend/tests/namedtest_<feature>.py - Use fixtures from
conftest.py— they're auto-discovered - Group related tests in classes (e.g.,
class TestMyFeature:) - Each test gets a fresh database transaction that rolls back
Example:
def test_my_feature(db, test_user, test_module, test_questions, test_schedule_config):
from app.services.my_service import do_something
result = do_something(test_module.id, test_user.id, db)
assert result.count > 0