Skip to content

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

cd saas-backend
uv run pytest tests/ -x -q

Frontend

cd saas-fronted
uv run pytest test/ -v

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

496 passed in 68.80s

Frontend

254 tests passing (2 skipped)
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

mock_repo = AsyncMock(spec=AuthRepositoryProtocol)
mock_repo.login.return_value = ("token", user)

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

  1. Write/update tests for the feature
  2. Run uv run pytest
  3. Analyze failures
  4. Fix code following Dependency Rule
  5. Repeat until passing