Proteus-Zweig: dataset.yaml-Pipeline und 5.0/8.0-Modellbaumvergleich
- create_dataset.py, compare_snapshots.py, rst_to_dataset.py: Proteus- Testdatensatz anlegen/vergleichen bzw. aus *.rst-Szenarien extrahieren - create_dataset.py: Feld-Alias-Fallback (FIELD_RENAMES) für bekannte Umbenennungen wie stock.move.uom -> unit, bidirektional - merge_dedup_rsts.py: Extrahierte YAMLs pro Version zusammenführen, versionsinterne Duplikate entfernen, abhängigkeitskorrekt sortieren - extract_model_tree.py: Modellbaum (Modelle/Felder) statisch aus dem Tryton-Quellcode ziehen, für 5.0 und 8.0 - model_diff.py, model_coverage.py: 5.0<->8.0-Modelländerungen finden und gegen die aktuelle Testdatenabdeckung abgleichen, priorisiert nach tatsächlicher Änderung - reports/*_merged.yaml: Extraktionsergebnisse für die aktiven Module (rohe *.rst-Quellen bewusst nicht mitversioniert) - Ordner doc ergänzt
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# Modellbaum-Vergleich (5.0 ↔ 8.0)
|
||||
|
||||
Werkzeug für die [Testdaten-Pipeline](TESTDATEN.md): Bevor Testdaten von
|
||||
Hand ergänzt werden, erstmal statisch (kein laufendes Tryton nötig)
|
||||
Schwarz auf Weiß sehen, welche Modelle/Felder es in einer Version
|
||||
überhaupt gibt - damit weder Felder aus 8.0 übernommen werden, die es in
|
||||
5.0 noch gar nicht gibt (würde beim Anlegen nur Fehler werfen), noch
|
||||
Aufwand in Modelle gesteckt wird, die sich zwischen den Versionen gar
|
||||
nicht verändert haben.
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. `extract_model_tree.py` – Modellbaum aus dem Quellcode ziehen
|
||||
|
||||
Scannt den Python-Code ausgewählter Module per AST (kein Import, keine
|
||||
laufende Instanz) und baut pro Modell (`__name__`) die Liste aller per
|
||||
`fields.X(...)` definierten Felder, mit Typ, Relationsziel
|
||||
(Many2One/One2Many/Many2Many/One2One/Reference) und - falls literal im
|
||||
Code erkennbar - `required`. Modelle werden über PoolMeta-Erweiterungen
|
||||
hinweg zusammengeführt: Fügt z. B. `stock_split` eine Klasse mit
|
||||
`__name__ = 'stock.move'` hinzu, landen deren Felder unter demselben
|
||||
Modell-Eintrag, mit Vermerk, aus welchem Modul sie stammen.
|
||||
|
||||
Pro Modell wird zusätzlich `persisted` erkannt (erbt die Klasse `ModelSQL`
|
||||
o. ä., oder nur `ModelView` - dann ist es ein reines Wizard-/
|
||||
Transient-Formular ohne eigene Tabelle).
|
||||
|
||||
```bash
|
||||
python3 extract_model_tree.py --repo /mnt/tryton \
|
||||
--modules company country currency party product ... \
|
||||
--output reports/model_tree_5.0.json --report reports/model_tree_5.0.md
|
||||
```
|
||||
|
||||
Für eine zweite Version denselben Befehl gegen einen zweiten Checkout
|
||||
laufen lassen (z. B. per `git worktree add /tmp/tryton-8.0 8.0`, ohne den
|
||||
Haupt-Checkout umzuschalten).
|
||||
|
||||
### 2. `model_diff.py` – zwei Modellbäume vergleichen
|
||||
|
||||
Sortiert jedes Modell in eine von fünf Kategorien:
|
||||
|
||||
- **entfernt** – Modell gibt es in Version A, nicht mehr in B
|
||||
- **geändert** – Feld(er) entfernt oder Typ/Relation/required geändert →
|
||||
echter Kandidat für einen Vergleichslauf
|
||||
- **neu** – Modell gibt es erst in B
|
||||
- **nur ergänzt** – nur neue Felder dazugekommen, Rest unverändert
|
||||
- **unverändert** – komplett identisch geblieben
|
||||
|
||||
```bash
|
||||
python3 model_diff.py --tree-a reports/model_tree_5.0.json --label-a 5.0 \
|
||||
--tree-b reports/model_tree_8.0.json --label-b 8.0 \
|
||||
--output reports/model_diff.json --report reports/model_diff.md
|
||||
```
|
||||
|
||||
### 3. `model_coverage.py` – gegen die aktuelle Testdaten-Abdeckung abgleichen
|
||||
|
||||
Vergleicht einen Modellbaum mit einer gemergten `dataset.yaml`
|
||||
(`reports/<version>_testdata_merged.yaml`, siehe
|
||||
[TESTDATEN.md](TESTDATEN.md)) und zeigt komplett unabgedeckte Modelle sowie
|
||||
pro teilweise abgedecktem Modell die ungenutzten Felder (required zuerst).
|
||||
|
||||
Drei Kategorien werden aus der Liste unabgedeckter Modelle per Default
|
||||
herausgefiltert (nie von Hand testdatenrelevant, jeweils per Flag wieder
|
||||
einschaltbar):
|
||||
|
||||
- `ir.*`/`res.*`-Kernmodelle (`--include-framework`)
|
||||
- Wizard-/Transient-Formulare, `persisted: false` (`--include-transient`)
|
||||
- automatisch verwaltete Many2Many-Verknüpfungstabellen, erkennbar am
|
||||
Bindestrich im Namen wie `party.party-party.category`
|
||||
(`--include-relations`)
|
||||
|
||||
Mit `--diff reports/model_diff.json` wird zusätzlich pro Modell die
|
||||
Diff-Kategorie aus Schritt 2 eingeblendet und die Liste danach sortiert:
|
||||
`geändert`/`entfernt` zuerst (lohnt sich, dort Testdaten zu ergänzen),
|
||||
`nur ergänzt`/`unverändert` zuletzt (dort ist über den reinen
|
||||
Codevergleich hinaus erstmal nichts Auffälliges zu erwarten).
|
||||
|
||||
```bash
|
||||
python3 model_coverage.py --model-tree reports/model_tree_5.0.json \
|
||||
--dataset reports/5_testdata_merged.yaml --diff reports/model_diff.json \
|
||||
--report reports/coverage_5.0.md
|
||||
```
|
||||
|
||||
## Bekannte Grenzen
|
||||
|
||||
- Rein statische Analyse: Felder, die nicht als einfaches
|
||||
`name = fields.X(...)` auf Klassenebene stehen (z. B. per Schleife/Helper
|
||||
dynamisch erzeugt), werden nicht erkannt.
|
||||
- `persisted`-Erkennung ist eine Textsuche über die Basisklassen-Ausdrücke
|
||||
(`ModelSQL`/`Workflow`/`DeactivableMixin`) - deckt den Normalfall ab, ist
|
||||
aber kein echtes Type-Checking.
|
||||
- Erkennt nur Unterschiede auf Ebene der Feld-**Definition** im Code
|
||||
(Typ/Relation/required). Laufzeitverhalten wie Constraints, Defaults oder
|
||||
DB-Spaltenpräzision kann trotzdem abweichen, ohne hier aufzufallen - dafür
|
||||
bleibt der eigentliche Testlauf über `create_dataset.py`/
|
||||
`compare_snapshots.py` nötig.
|
||||
Reference in New Issue
Block a user