Contract Tests
API contract tests organized by Django app, with optional workflow tests.
Testing Modes
Two modes via CONTRACT_TEST_MODE environment variable:
| Mode | Command | Description |
|---|---|---|
| api (default) | pytest tests/contracts/ |
Fast, Django test client, test DB |
| live | CONTRACT_TEST_MODE=live pytest tests/contracts/ |
Real HTTP, LiveServerTestCase, test DB |
Mode Comparison
api (default) |
live |
|
|---|---|---|
| Base class | APITestCase |
LiveServerTestCase |
| HTTP | In-process (Django test client) | Real HTTP via requests |
| Auth | force_authenticate() |
JWT tokens via API |
| Database | Django test DB (isolated) | Django test DB (isolated) |
| Speed | ~3-5 sec | ~15-30 sec |
| Server | None (in-process) | Auto-started by Django |
Key Point: Both Modes Use Test Database
Neither mode touches your real database. Django automatically:
- Creates a test database (prefixed with
test_) - Runs migrations
- Destroys it after tests complete
File Structure
tests/contracts/
├── base.py # Mode switcher (imports from base_api or base_live)
├── base_api.py # APITestCase implementation
├── base_live.py # LiveServerTestCase implementation
├── conftest.py # pytest-django configuration
├── endpoints.py # API paths (single source of truth)
├── helpers.py # Shared test data helpers
│
├── mascotas/ # Django app: mascotas
│ ├── test_pet_owners.py
│ ├── test_pets.py
│ └── test_coverage.py
│
├── productos/ # Django app: productos
│ ├── test_services.py
│ └── test_cart.py
│
├── solicitudes/ # Django app: solicitudes
│ └── test_service_requests.py
│
└── workflows/ # Multi-step API sequences (e.g., turnero booking flow)
└── test_turnero_general.py
Running Tests
# All contract tests
pytest tests/contracts/
# Single app
pytest tests/contracts/mascotas/
# Single file
pytest tests/contracts/mascotas/test_pet_owners.py
# Live mode (real HTTP)
CONTRACT_TEST_MODE=live pytest tests/contracts/