Files
tryton-db-migration/doc/TESTDATEN.md
T
uha4 c0dd24b6c5 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
2026-08-22 10:52:13 +02:00

105 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Proteus-Testdaten-Pipeline
Ergänzender Ansatz zur [Codeanalyse](UPDATEANALYSE.md): 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.py` und `rsts_merge_dedup.py` sind gegen echte
`scenario_*.rst`-Dateien aus `/mnt/tryton` (5.0- und 8.0-Branch) getestet,
siehe `reports/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.py` und `compare_snapshots.py` sind 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](MODELLVERGLEICH.md)
- das steuert, wo als Nächstes von Hand YAML-Records ergänzt werden.