- 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
4.9 KiB
Proteus-Testdaten-Pipeline
Ergänzender Ansatz zur Codeanalyse: Statt den
__register__-Code zu lesen, wird ein deklarativ definierter Testdatensatz
über Proteus in zwei frisch installierten Tryton-Instanzen (5.0 und 8.0)
tatsächlich angelegt. Ziel ist, dieselbe Datei gegen beide Versionen laufen
zu lassen, damit sowohl die Skript-Ausgabe (compare_snapshots.py) als
auch anschließend die SQL-Dumps beider Datenbanken vergleichbar sind -
dafür müssen inhaltlich identische Daten in derselben Reihenfolge
eingespielt werden.
Workflow
tests/scenario_*.rst (Tryton-Repo, pro Modul)
│ rst_to_dataset.py
▼
rsts/<version>e/*.yaml (ein YAML-Record pro angelegtem Proteus-Objekt)
│ rsts_merge_dedup.py
▼
reports/<version>_testdata_merged.yaml (dedupliziert, abhängigkeitskorrekt sortiert)
│ create_dataset.py --database ...
▼
snapshot_<version>.json
│ compare_snapshots.py snapshot_a.json snapshot_b.json
▼
Fund-Liste: status_changed / value_changed / missing_record
1. rst_to_dataset.py – Testdaten aus den Modul-eigenen Tests extrahieren
Tryton-Module bringen eigene tests/scenario_*.rst-Doctests mit (ausführbarer
Proteus-Code in >>>-Zeilen). Das Skript parst diese Dateien per AST und
erkennt:
>>> Party = Model.get('party.party')
>>> party = Party(name='Testfirma GmbH')
>>> party.vat_number = '123'
>>> party.save()
→ wird zu einem YAML-Record mit key, model, fields. Referenzen auf
zuvor im selben File angelegte Records werden zu {"$ref": "..."},
Decimal(...)/date(...) zu {"$decimal": ...}/{"$date": ...}. Alles
nicht automatisch Auflösbare (Wizards, .click(...), Helper-Funktionsaufrufe)
wird als {"$manual": "<Ausdruck>"} markiert oder ganz übersprungen -
bewusst sichtbar unvollständig statt still falsch.
Record-Keys werden mit dem Dateinamen präfixiert, damit beim Zusammenführen mehrerer Module keine Kollisionen entstehen.
2. rsts_merge_dedup.py – pro Version zusammenführen
Liest alle rsts/<version>e/*.yaml eines Verzeichnisses ein und entfernt
Records mit identischem model+fields (z. B. dasselbe
Basis-product.template, das in vielen Szenarien wiederverwendet wird).
$ref-Verweise auf entfernte Duplikate werden auf den behaltenen Record
umgeschrieben. Danach wird per Kahn-Algorithmus so sortiert, dass
$ref-Abhängigkeiten immer VOR dem referenzierenden Record stehen, aber
innerhalb der Freiheitsgrade weiterhin nach model gruppiert wird.
Achtung: Dedupliziert bewusst GLOBAL, auch innerhalb derselben Datei.
Bei Szenarien, die zwei absichtlich gleich aussehende Records anlegen (z. B.
scenario_party_replace.rst: zwei Parteien namens "Pam", um eine zu
ersetzen), verändert das den Sinn des Szenarios - für einen groben
Testdatensatz ist das in Ordnung, für szenario-treue Tests nicht.
3. create_dataset.py – gegen eine echte Instanz anlegen
Legt die Records der Reihe nach per Proteus an, liest jeden Wert danach
FRISCH VOM SERVER zurück (nicht aus dem lokalen Proteus-Cache), damit
automatische Reformatierung sichtbar wird. Ergebnis: ein JSON-Snapshot
(status/error/stored pro Record).
Feld-Umbenennungen zwischen Versionen (FIELD_RENAMES): Da dieselbe
YAML gegen mehrere Versionen laufen soll, aber Felder umbenannt werden
können (bestätigt: stock.move.uom → stock.move.unit zwischen 5.0 und
8.0), prüft das Skript pro Modell zuerst per fields_get(), ob der
YAML-Feldname auf dem jeweiligen Server existiert, und weicht sonst auf
einen bekannten, bidirektionalen Alias aus. Ein wirklich unbekanntes Feld
bleibt trotzdem ein Fehler - das ist ja gerade das gesuchte Signal für eine
echte Schema-Änderung. Weitere Umbenennungen bei Bedarf in FIELD_RENAMES
ergänzen, sobald ein Lauf sie aufdeckt.
4. compare_snapshots.py – zwei Versionen gegenüberstellen
Vergleicht zwei Snapshots (gleiche YAML, zwei Versionen/Datenbanken) und
markiert status_changed (ein Record schlägt nur in einer Version fehl -
Kandidat für Format-/Constraint-/Pflichtfeld-Änderung), value_changed
(gespeicherter Wert weicht trotz gleichem Input ab - automatische
Reformatierung) und missing_record.
Stand
rst_to_dataset.pyundrsts_merge_dedup.pysind gegen echtescenario_*.rst-Dateien aus/mnt/tryton(5.0- und 8.0-Branch) getestet, siehereports/5_testdata_merged.yaml/reports/8_testdata_merged.yaml(jeweils NUR aus den Szenarien der jeweiligen Version extrahiert, noch NICHT zu einer gemeinsamen Datei zusammengeführt).create_dataset.pyundcompare_snapshots.pysind noch nicht gegen eine echte Tryton-Instanz gelaufen (nur syntaktisch geprüft).- Welche Modelle/Felder überhaupt Testdaten brauchen bzw. wo sich 5.0 und
8.0 tatsächlich unterscheiden, siehe MODELLVERGLEICH.md
- das steuert, wo als Nächstes von Hand YAML-Records ergänzt werden.