Aller au contenu

ADR-041 : Infrastructure de test partagée pour les paquets opt-in

Statut

Acceptée, Forge 1.0.0-beta.17 (ticket GOV-ADR-STATUS-RESOLVE-001).
Proposé en 1.0.0-beta.x (ticket OPTIN-TEST-SUPPORT-001).

La décision est appliquée : le paquet forge-mvc-testing (FakeRequest plus
plugin pytest) est distribué en dev-only ; le conftest.py racine est réduit et
les paquets opt-in portent leurs tests via ce paquet.

Débloque l'ADR-040 (surface de test par paquet) : quatre paquets ont pu migrer
leurs tests unitaires (stats, workflow, audio, mail), mais les huit
autres en sont empêchés par une dépendance à l'infrastructure de test partagée
du tests/ racine.


Date

2026-06-21


Contexte

Migrer les tests unitaires d'un opt-in vers packages/<paquet>/tests/
(ADR-040) suppose qu'ils soient autonomes. Or tests/conftest.py fournit
une infrastructure partagée dont dépendent 61 fichiers de test, opt-ins
inclus :

  • des fixtures autouse qui configurent le noyau Forge pour chaque test :
    configure_forge_kernel (vues + SQL en tmp_path, UPLOAD_ROOT isolé),
    clear_sessions, clear_rate_limits, clear_upload_rate_limits ;
  • la fixture fake_request et la classe FakeRequest (tests/fake_request.py)
    pour simuler une requête de contrôleur.

Déplacés tels quels dans un paquet, ces tests perdent l'accès à ces fixtures
(conftest.py racine ne s'applique qu'au sous-arbre tests/) et échouent en
masse (« fixture not found »). Tentative mesurée : 100 échecs. Le filtre
« n'importe pas cli/mvc » est donc insuffisant : le vrai couplage est
l'infrastructure de test, pas le code applicatif.

Incident à noter : tests/conftest.py mentionne forge_mvc_workflow et a été
faussement déplacé par un filtre trop large, ce qui casse toute la racine.
Tout futur déplacement doit exclure conftest.py et tracer l'usage de fixtures.


Décision

Extraire l'infrastructure de test partagée dans un paquet de test-support
dédié, réservé au développement
: packages/forge-mvc-testing/
(module forge_mvc_testing).

Il fournit :

  1. FakeRequest (importable : from forge_mvc_testing import FakeRequest) ;
  2. un plugin pytest (point d'entrée pytest11) exposant les fixtures
    partagées (configure_forge_kernel autouse, clear_*, fake_request).
    Quand le paquet est installé dans l'environnement de test, ses fixtures sont
    disponibles partout, racine comme paquets, sans conftest.py dupliqué.

Conséquences de câblage :

  • forge-mvc-testing est une dépendance de développement uniquement
    (déclarée dans requirements-dev.txt et dans l'extra [test] de chaque
    opt-in). Il n'est jamais une dépendance runtime, jamais installé par
    les utilisateurs : leurs suites de tests ne sont pas polluées par les fixtures
    autouse de Forge.
  • tests/conftest.py racine se réduit à presque rien (le plugin fournit tout) ;
    tests/fake_request.py est supprimé au profit de forge_mvc_testing.
  • Une fois en place, les huit paquets restants (mfa, rbac, files,
    images, iot, video, pivot, i18n) migrent leurs tests unitaires
    propres, qui ne dépendent plus que de forge_mvc_<paquet> + core +
    forge_mvc_testing (présent en dev).

Alternatives écartées

  • Plugin pytest porté par le core (core.testing + pytest11) : rejeté.
    Le core est une dépendance runtime de tous les opt-ins ; un plugin autouse
    dans le core s'activerait dans la suite de tests de l'utilisateur, et
    configure_forge_kernel reconfigurerait son noyau. Trop intrusif (contraire
    au principe 8 : pas d'effet caché côté utilisateur).
  • Réplication du conftest.py dans chaque paquet : rejeté. ~90 lignes de
    fixtures dupliquées sur huit paquets, avec dérive garantie (contraire au
    principe 11 : une seule façon officielle).
  • Laisser ces tests à la racine : possible, mais les huit paquets restent
    alors non autovérifiables, ce que l'ADR-040 visait à corriger.

Plan d'exécution séquencé

  1. Créer packages/forge-mvc-testing/ : FakeRequest + plugin pytest
    (fixtures déplacées depuis tests/conftest.py). Pas publié sur PyPI (ou en
    dev-only), pyproject.toml minimal.
  2. Brancher : requirements-dev.txt + extra [test] des opt-ins ; réduire
    tests/conftest.py à un repli ; supprimer tests/fake_request.py.
  3. Vérifier la racine inchangée (suite complète verte), le plugin remplace le
    conftest sans régression.
  4. Migrer les huit paquets, un par un, en ne déplaçant que les tests
    réellement propres (exclure conftest.py, vérifier l'absence de
    from tests[.] et de fixtures hors forge_mvc_testing), run racine et
    autonome verts à chaque paquet.

Conséquences

Positives :

  • Les douze opt-ins peuvent porter leurs tests unitaires, autovérifiables et
    exécutables en autonome.
  • Une seule source pour FakeRequest et les fixtures (principe 11).
  • Les suites de test des utilisateurs ne sont pas affectées (test-support
    dev-only).

Négatives / coûts :

  • Un paquet de plus à maintenir (mais de test, simple, non publié).
  • Migration en deux temps (infra d'abord, puis les huit paquets).

Charte appliquée

  • Principe 11, une seule façon officielle (infra de test unique).
  • Principe 8, noyau minimal (l'infra de test ne va pas dans le core).
  • Principe 6, tester avant d'élargir (racine validée avant de migrer les huit).

ADR liés

  • Débloque l'ADR-040 (surface de test par paquet).
  • Cohérent avec l'ADR-005 (packaging hybride monorepo + multi-distributions).