Utilitaires de Test

Des utilitaires de test basés sur pytest sont fournis pour faciliter l’écriture de tests dans un environnement multi-tenant.

Module : src.testing

Fixtures pytest — Cycle de vie du tenant

Module : src.testing.testcases

src.testing.tenant_fixture(fixture, scope='session')[source]

Fixture session-scoped qui crée un tenant de test avec son schéma provisionné. Le tenant est réutilisé pour tous les tests de la session puis détruit à la fin.

src.testing.tenant_context_fixture(fixture, scope='function')[source]

Fixture function-scoped qui active le contexte tenant pour un test. Active le backend d’isolation et positionne les contextvars.

src.testing.tenant_tx_context_fixture(fixture, scope='function')[source]

Même chose que tenant_context_fixture mais utilise transactional_db pour les tests nécessitant des commits réels.

# conftest.py
from src.testing import tenant_fixture, tenant_context_fixture  # noqa: F401

# test_invoices.py
def test_create_invoice(tenant_context_fixture):
    # Le contexte tenant est automatiquement actif
    invoice = Invoice.objects.create(
        number="INV-001",
        total=1500.00,
    )
    assert invoice.tenant_id == tenant_context_fixture.id

Fixtures pytest — Schéma réutilisable

Module : src.testing.fixtures

src.testing.tenant_schema(fixture, scope='session')[source]

Fixture session-scoped qui crée un tenant de test une seule fois.

# conftest.py
from src.testing.fixtures import tenant_schema  # noqa: F401
src.testing.tenant_context(fixture, scope='function')[source]

Fixture function-scoped qui active le contexte tenant pour chaque test.

# conftest.py
from src.testing.fixtures import tenant_context  # noqa: F401

def test_products(tenant_context):
    products = Product.objects.all()
    assert products.count() >= 0

Helpers

Module : src.testing.helpers

src.testing.create_test_tenant(slug: str = 'test-tenant') Tenant[source]

Crée un tenant de test avec provisionnement du schéma.

src.testing.drop_test_tenant(tenant) None[source]

Supprime un tenant de test et son schéma.

src.testing.create_test_user(email: str = 'test@example.com', **kwargs) User[source]

Crée un utilisateur de test.

src.testing.create_test_membership(user, tenant, roles=None, abac_attributes=None) TenantMembership[source]

Crée une membership de test.

Factories

Module : src.testing.factories

class src.testing.TenantRequestFactory(APIRequestFactory)

Factory de requêtes DRF qui injecte automatiquement le header X-Tenant-ID.

from src.testing.factories import TenantRequestFactory

factory = TenantRequestFactory(tenant=my_tenant, user=my_user)
request = factory.get("/api/v1/invoices/")
# Header X-Tenant-ID automatiquement ajouté
src.testing.create_test_policy(**kwargs) Policy

Crée une politique ABAC de test avec des valeurs par défaut raisonnables.

src.testing.evaluate_test_policy(policy, subject_attributes=None, action="read", ...) EvaluationResult

Évalue une politique unique avec le contexte fourni. Crée le PDP et retourne un EvaluationResult.

from src.testing.factories import create_test_policy, evaluate_test_policy

@pytest.mark.django_db
def test_admin_can_delete():
    policy = create_test_policy(
        name="Admin delete",
        effect="allow",
        actions=["delete"],
        resource_type="Invoice",
        subject_conditions={"field": "roles", "op": "contains", "value": "admin"},
    )

    result = evaluate_test_policy(
        policy,
        action="delete",
        subject_attributes={"roles": ["admin"]},
    )
    assert result.decision == "allow"