Testing¶
Test Structure¶
tests/
├── conftest.py # Shared fixtures
├── auth/
│ ├── unit/
│ │ ├── test_user_entity.py
│ │ └── test_login_usecase.py
│ ├── integration/
│ └── security/
├── shipments/
│ ├── unit/
│ └── integration/
└── security/
├── test_sql_injection.py
└── test_tenant_isolation.py
Running Tests¶
Backend¶
Frontend¶
Test Types¶
Unit Tests¶
Test individual components in isolation:
@pytest.mark.asyncio
async def test_login_usecase_success():
mock_repository = AsyncMock()
mock_user = User(id="u1", email="a@b.com", name="T", role="user", tenant_id="t1")
mock_repository.login.return_value = ("token", mock_user)
usecase = LoginUseCase(mock_repository)
result = await usecase.execute("a@b.com", "password")
assert result is not None
Integration Tests¶
Test API endpoints:
@pytest.mark.asyncio
async def test_create_shipment():
response = await client.post(
"/api/v1/shipments",
headers={"Authorization": f"Bearer {token}"},
json={...}
)
assert response.status_code == 201
Security Tests¶
# Tenant isolation
uv run pytest tests/security/test_tenant_isolation.py -v
# SQL injection prevention
uv run pytest tests/security/test_sql_injection.py -v
Test Coverage¶
Backend¶
Frontend¶
| Module | Count |
|---|---|
| core/error | 3 |
| core/theme | 6 |
| auth/domain | 22 |
| core/storage | 8 |
| validators | 13 |
| translations | 20 |
| core/security | 37 |
| modules/tracking | 37 |
| modules/shipments | 18 |
| core/realtime | 12 |
Mocking¶
Repository Mock¶
HTTP Mock¶
from httpx import AsyncClient, MockTransport
async def test_api():
async with AsyncClient(transport=MockTransport(handler)) as client:
response = await client.get("/api/v1/shipments")
Test Fixtures¶
@pytest.fixture
def auth_headers():
return {"Authorization": f"Bearer {test_token}"}
@pytest.fixture
async def db_session():
async with async_session() as session:
yield session
TDD Protocol¶
- Write/update tests for the feature
- Run
uv run pytest - Analyze failures
- Fix code following Dependency Rule
- Repeat until passing