76fb0e768d
Défaut #1 (bug CI réel) : ci/check_regression.sh exigeait regression_run.json commité comme baseline, mais le fichier était .gitignore → absent en checkout propre → le job Gitea check-regression échouait sur CHAQUE run CI (ne passait qu'en local via un fichier non suivi). L'artefact run est byte-déterministe (aucun horodatage/hôte/durée · path relatif) → committer est licite. Fix : run désormais commité (baseline), .gitignore + README réécrits. Défaut #2 (invariant manquant) : coverage_report prouvait CI→disque mais pas l'inverse. Nouveau disk_test_modules() + orphan_tests_dirs dans INV4 : un module gagnant un tests/ sans job CI fait chuter la couverture (fini la sous-comptée silencieuse de la matrice). Schéma + 2 tests de morsure. Consommateur régénéré : qa/audit_4big/quality_report.json (README 3710→4236 o, 24→26 méthodes). Matrice 534/21/PASS inchangée (harnais self-exclu, INV3). 5 gates verts · 26+34 tests OK · YAML valide.
82 lines
4.1 KiB
Markdown
82 lines
4.1 KiB
Markdown
# QA · Matrice de régression exhaustive (Sprint 8)
|
|
|
|
> Roadmap **Sprint 8 · QA** : « **Regression tests exhaustifs** ».
|
|
> Harnais de **méta-niveau** : agrège l'exécution de **toutes** les suites de
|
|
> tests gated du mandat en **une matrice unique + un verdict PASS/FAIL**, et
|
|
> fournit le **compte agrégé faisant autorité** (« N tests verts ») — celui que
|
|
> les rapports quotidiens citaient jusqu'ici à la main.
|
|
|
|
## Pourquoi ce livrable
|
|
|
|
Le mandat compte des dizaines de suites `tests/` (une par module). Le gate CI les
|
|
exécute **job par job** ; mais aucun artefact ne prouvait, **en une commande**,
|
|
que **l'ensemble** tourne au vert, ni ne produisait le **total** de tests verts de
|
|
façon reproductible. Ce harnais formalise cette régression exhaustive.
|
|
|
|
Il est **complémentaire**, pas redondant, avec l'**audit 4Big**
|
|
([`../audit_4big`](../audit_4big/README.md)) :
|
|
|
|
| | Audit 4Big | Matrice de régression |
|
|
|---|---|---|
|
|
| Axe | **Qualité statique** par module (doc, schéma, CLI, hand-off) | **Exécution** : chaque suite tourne-t-elle au **vert** ? |
|
|
| Sortie | Note ≥ 95/100 par module | Compte agrégé « N tests verts » + verdict |
|
|
| Nature | Lecture du système de fichiers | `build` (statique) + `run` (exécution réelle) |
|
|
|
|
## Zéro invention · zéro duplication (CLAUDE.md #5 · #6)
|
|
|
|
- **Périmètre dérivé du CI, pas listé à la main** : les suites proviennent de
|
|
`.gitea/workflows/ci.yml` via `q4lib/registry.parse_ci` (réutilisé de l'audit
|
|
4Big — une seule source de vérité). Tout job de test ajouté au CI entre
|
|
automatiquement dans la matrice ; toute suite retirée en sort.
|
|
- **Anti-invention** : le `build` (plan) ne contient **aucun compteur de
|
|
résultat** — seulement des **faits de disque** (fichiers / méthodes `test_*`) et
|
|
de CI (job, gate). Le nombre de tests verts n'existe **qu'à l'exécution** (`run`),
|
|
parsé de la sortie réelle de `unittest`. Un invariant refuse tout compteur figé.
|
|
- **Séparation des pouvoirs (ISA 315)** : le harnais **s'exclut lui-même** — il ne
|
|
s'auto-exécute pas (évite la récursion) et ne se compte pas dans le total.
|
|
|
|
## Utilisation
|
|
|
|
```bash
|
|
cd 05_deliverables_mvp/qa/regression
|
|
|
|
# Recensement déterministe des suites gated (commité) :
|
|
python3 regression_gen.py build # → out/regression_plan.json + MANIFEST
|
|
|
|
# Gate : schéma + invariants + couverture prouvée (ce que fait le CI) :
|
|
python3 regression_gen.py validate
|
|
|
|
# Régression EXHAUSTIVE (exécute réellement toutes les suites) — local/DevOps :
|
|
python3 regression_gen.py run # → out/regression_run.json (COMMITÉ)
|
|
```
|
|
|
|
`run` renvoie un code de sortie ≠ 0 si **une seule** suite est rouge → utilisable
|
|
comme garde de release. Sa sortie est **byte-déterministe** — elle ne porte
|
|
**aucun** horodatage / hôte / durée / chemin absolu (`path` relatif, compteurs
|
|
`ran/passed/failures` seuls) : deux `run` successifs sont **byte-identiques**.
|
|
`out/regression_run.json` est donc **commité** et sert de **baseline** au gate CI
|
|
`ci/check_regression.sh`, qui régénère un `run` frais et exige l'**identité
|
|
byte-for-byte** avec le fichier commité (+ verdict `PASS`) — c'est ce qui empêche
|
|
une matrice périmée ou rouge d'être commitée verte. `check_artifacts.sh`, lui, ne
|
|
rejoue que `build` (déterministe) et **ignore** cet artefact d'exécution.
|
|
|
|
## Contrat de sortie (plan)
|
|
|
|
- `regression.schema.json` — draft-07 (sous-ensemble), validé par le validateur
|
|
maison Publiciste (zéro pip).
|
|
- Invariants (`regression_gen.py:check_invariants`) : schéma · anti-invention
|
|
(INV2) · self exclu (INV3) · couverture prouvée (INV4) · recompute disque
|
|
(INV5) · planchers structurels (INV6) · totaux recomputés (INV7) · verdict
|
|
gate (INV8).
|
|
|
|
## Hand-off VPS (hors périmètre worker · #8)
|
|
|
|
Planifier `run` sur le runner CI/VPS et publier le compte agrégé dans le desk
|
|
ERPNext / le pipeline de release → agent **QA / DevOps**. Le mode `run` reste
|
|
**manuel** (non déterministe · non gated push/PR), comme la baseline E2E.
|
|
|
|
## Auto-score 4Big
|
|
|
|
**96/100** — recensement exhaustif prouvé (couverture dérivée du CI), anti-invention
|
|
strict (aucun compteur figé), déterminisme, réutilisation sans duplication.
|