[FIX] test_foerderer.py: CSV-Exporttests an die verpackten Separator-Zeilen anpassen
Commit e2f0384 (vor dieser Session) liess EXPORTCSV/EXPORTSIVAS auch die in
VF_n-Blockdefinitionen verpackten Separator_SP-Sensoren als eigene Zeile
exportieren (TeileArt "ILS 2.0 Separator"). tests/test_foerderer.py wurde
seitdem nicht angepasst und nahm weiter an, JEDE Zeile sei eine Vario-
Strecke - drei Tests schlugen daher fehl, sobald die CSV tatsaechlich
vorlag (39 statt 13 Zeilen: 13 Vario- + 26 Separator-Zeilen).
Neu NEBEN_TEILEARTEN = {"ILS 2.0 Separator"} plus zwei Filter-Helfer
(_vario_rows/_separator_rows). test_vario_teileart, test_merkmale_felder
und test_anzahl_csv_zeilen_entspricht_gebaut pruefen jetzt nur noch die
Vario-Zeilen (verifiziert: 13 Vario- + 26 Separator-Zeilen in der aktuellen
CSV, Summe stimmt).
Statt die Separator-Zeilen nur zu ignorieren, zwei neue, eigenstaendige
Tests:
- test_teileart_bekannt: jede Zeile ist Vario-Strecke ODER eine bekannte
Neben-TeileArt - faengt eine dritte, unerwartete Art, die die beiden
Filter sonst stillschweigend durchliessen.
- test_separator_merkmale_felder: die Separator-Merkmale haben ihr eigenes,
kleineres Pflichtfeld-Schema (Zuordnung, ARTINR) statt der Vario-Felder.
- test_separator_zuordnung_konsistent: der eigentliche Beweis, dass
csv:sep-proxies-erzeugen die Sensoren dem RICHTIGEN Wrapper zuordnet -
jede Separator-Zuordnung zeigt auf eine Vario-TeileId derselben Datei,
und je Vario-Zeile stimmt die Anzahl ihrer Separatoren mit dem eigenen
Merkmal Anzahl_Separator ueberein (test_export_ids.py prueft nur, dass
die Zuordnung ueberhaupt auf eine bekannte ID zeigt, nicht auf die
richtige). Gegengeprobt: eine verfaelschte Zuordnung wird erkannt.
Verifiziert: alle 27 Tests in test_foerderer.py gruen (vorher 3 FAILED),
Gesamtsuite 188 passed / 0 failed / 19 skipped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+98
-8
@@ -7,7 +7,10 @@ Prueft:
|
||||
1. Status-Werte und Vollstaendigkeit (foerderer_results.json)
|
||||
2. Mathematische Invarianten (Laengen, Winkel, Richtung)
|
||||
3. Geometrisch unmoegliche Faelle
|
||||
4. CSV-Export-Struktur (foerderer_tests_export.csv, aus TEST_EXPORT_ALL)
|
||||
4. CSV-Export-Struktur (foerderer_tests_export.csv, aus TEST_EXPORT_ALL) -
|
||||
seit csv:sep-proxies-erzeugen (Commit e2f0384) enthaelt die CSV neben
|
||||
den Vario-Zeilen auch eine Zeile je verpacktem Separator-Sensor; siehe
|
||||
NEBEN_TEILEARTEN und TestFoerdererExportCSV._vario_rows/_separator_rows.
|
||||
5. Sivas-Export-Struktur (foerderer_tests_sivas.csv, aus TEST_EXPORT_ALL)
|
||||
"""
|
||||
|
||||
@@ -17,6 +20,15 @@ import os
|
||||
import pytest
|
||||
|
||||
|
||||
# TeileArt-Werte, die einen SENSOR beschreiben statt einer Vario-Strecke -
|
||||
# csv:sep-proxies-erzeugen (export.lsp, Commit e2f0384) erfasst seither auch
|
||||
# Separator_SP-Symbole, die als Sub-INSERT in der VF_n-Blockdefinition
|
||||
# verpackt sind, und exportiert je Fund eine eigene Zeile. Foerderer kennt
|
||||
# nur diese eine Sensorart (kein Scanner); die vollstaendige Liste steht in
|
||||
# test_export_ids.py:SENSOR_TEILEARTEN.
|
||||
NEBEN_TEILEARTEN = {"ILS 2.0 Separator"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Hilfsfunktionen
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -211,6 +223,16 @@ class TestFoerdererExportCSV:
|
||||
return None
|
||||
return row[i]
|
||||
|
||||
def _vario_rows(self):
|
||||
"""Nur die eigentlichen Foerderer-Zeilen, ohne die mitexportierten
|
||||
Separator-Sensoren (siehe NEBEN_TEILEARTEN)."""
|
||||
return [row for row in self.rows
|
||||
if self._cell(row, "TeileArt") not in NEBEN_TEILEARTEN]
|
||||
|
||||
def _separator_rows(self):
|
||||
return [row for row in self.rows
|
||||
if self._cell(row, "TeileArt") == "ILS 2.0 Separator"]
|
||||
|
||||
def test_header_felder(self):
|
||||
"""CSV-Header muss die erwarteten Spalten enthalten (Reihenfolge/Zusatz-
|
||||
spalten wie Insertpoint/K1-K4/Warnungen egal - per Name geprueft)."""
|
||||
@@ -227,9 +249,10 @@ class TestFoerdererExportCSV:
|
||||
assert len(self.rows) > 0, "foerderer_tests_export.csv enthaelt keine Daten"
|
||||
|
||||
def test_vario_teileart(self):
|
||||
"""Alle Eintraege muessen TeileArt 'ILS 2.0 Strecke' haben (VarioFoerderer
|
||||
"""Jede Vario-Zeile (ohne die mitexportierten Separator-Sensoren, siehe
|
||||
NEBEN_TEILEARTEN) muss TeileArt 'ILS 2.0 Strecke' haben (VarioFoerderer
|
||||
ist ein Streckentyp, siehe export_csv.py:process_blocks)."""
|
||||
for i, row in enumerate(self.rows):
|
||||
for i, row in enumerate(self._vario_rows()):
|
||||
teileart = self._cell(row, "TeileArt")
|
||||
if teileart is None:
|
||||
continue
|
||||
@@ -237,6 +260,19 @@ class TestFoerdererExportCSV:
|
||||
f"Zeile {i + 2}: TeileArt='{teileart}', erwartet 'ILS 2.0 Strecke'"
|
||||
)
|
||||
|
||||
def test_teileart_bekannt(self):
|
||||
"""Jede Zeile ist entweder eine Vario-Strecke oder eine der bekannten
|
||||
Neben-TeileArten - keine unerwartete dritte Art (die die beiden obigen
|
||||
Filter sonst stillschweigend durchliesse)."""
|
||||
bekannt = {"ILS 2.0 Strecke"} | NEBEN_TEILEARTEN
|
||||
for i, row in enumerate(self.rows):
|
||||
teileart = self._cell(row, "TeileArt")
|
||||
if teileart is None:
|
||||
continue
|
||||
assert teileart.strip('"') in bekannt, (
|
||||
f"Zeile {i + 2}: unbekannte TeileArt '{teileart}'"
|
||||
)
|
||||
|
||||
def test_anzahl_spalte_ist_eins(self):
|
||||
"""Anzahl-Spalte muss fuer alle Zeilen '1' sein."""
|
||||
for i, row in enumerate(self.rows):
|
||||
@@ -259,10 +295,27 @@ class TestFoerdererExportCSV:
|
||||
pytest.fail(f"Zeile {i + 2}: Merkmale ist kein valides JSON: {e}")
|
||||
|
||||
def test_merkmale_felder(self):
|
||||
"""Merkmale muessen alle Pflichtfelder enthalten."""
|
||||
"""Merkmale der Vario-Zeilen muessen alle Pflichtfelder enthalten. Die
|
||||
mitexportierten Separator-Sensoren haben ein eigenes, kleineres Schema
|
||||
(siehe test_separator_merkmale_felder) und sind hier ausgenommen."""
|
||||
required = {"Typ", "Winkel", "DeltaH_mm", "DeltaL_mm",
|
||||
"L_VF_m", "Hoehe_Von_mm", "Hoehe_Bis_mm"}
|
||||
for i, row in enumerate(self.rows):
|
||||
for i, row in enumerate(self._vario_rows()):
|
||||
zelle = self._cell(row, "Merkmale")
|
||||
if zelle is None:
|
||||
continue
|
||||
merkmale = json.loads(zelle)
|
||||
missing = required - set(merkmale.keys())
|
||||
assert not missing, (
|
||||
f"Zeile {i + 2}: Fehlende Merkmale-Felder: {missing}"
|
||||
)
|
||||
|
||||
def test_separator_merkmale_felder(self):
|
||||
"""Merkmale der mitexportierten Separator-Sensoren muessen die
|
||||
Zuordnung zu ihrem Vario-Wrapper tragen (siehe
|
||||
test_separator_zuordnung_konsistent) sowie ARTINR."""
|
||||
required = {"Zuordnung", "ARTINR"}
|
||||
for i, row in enumerate(self._separator_rows()):
|
||||
zelle = self._cell(row, "Merkmale")
|
||||
if zelle is None:
|
||||
continue
|
||||
@@ -273,14 +326,51 @@ class TestFoerdererExportCSV:
|
||||
)
|
||||
|
||||
def test_anzahl_csv_zeilen_entspricht_gebaut(self):
|
||||
"""CSV-Zeilenanzahl muss Anzahl GEBAUT-Testfaellen entsprechen."""
|
||||
"""Anzahl der Vario-Zeilen (ohne die mitexportierten Separatoren) muss
|
||||
der Anzahl GEBAUT-Testfaellen entsprechen."""
|
||||
results = _load_foerderer_results()
|
||||
anzahl_gebaut = sum(1 for r in results if r["status"] == "GEBAUT")
|
||||
assert len(self.rows) == anzahl_gebaut, (
|
||||
f"CSV hat {len(self.rows)} Zeilen, "
|
||||
vario_rows = self._vario_rows()
|
||||
assert len(vario_rows) == anzahl_gebaut, (
|
||||
f"CSV hat {len(vario_rows)} Vario-Zeilen, "
|
||||
f"erwartet {anzahl_gebaut} (Anzahl GEBAUT-Faelle)"
|
||||
)
|
||||
|
||||
def test_separator_zuordnung_konsistent(self):
|
||||
"""Jeder Separator zeigt (ueber Merkmale.Zuordnung) auf die TeileId
|
||||
eines Vario-Eintrags DERSELBEN Datei, und je Vario-Zeile stimmt die
|
||||
Anzahl seiner Separatoren mit ihrem eigenen Merkmal Anzahl_Separator
|
||||
ueberein. Das ist der eigentliche Beweis, dass
|
||||
csv:sep-proxies-erzeugen die verpackten Sensoren dem richtigen
|
||||
Wrapper zuordnet - test_export_ids.py::test_sensor_zuordnung_existiert
|
||||
prueft nur, dass die Zuordnung ueberhaupt auf eine bekannte ID zeigt."""
|
||||
vario_rows = self._vario_rows()
|
||||
vario_ids = {self._cell(row, "TeileId") for row in vario_rows}
|
||||
|
||||
separator_je_id = {}
|
||||
for row in self._separator_rows():
|
||||
zelle = self._cell(row, "Merkmale")
|
||||
if zelle is None:
|
||||
continue
|
||||
zuordnung = json.loads(zelle).get("Zuordnung")
|
||||
assert zuordnung in vario_ids, (
|
||||
f'Separator {self._cell(row, "TeileId")}: Zuordnung '
|
||||
f"'{zuordnung}' zeigt auf keine Vario-Zeile dieser Datei"
|
||||
)
|
||||
separator_je_id[zuordnung] = separator_je_id.get(zuordnung, 0) + 1
|
||||
|
||||
for row in vario_rows:
|
||||
tid = self._cell(row, "TeileId")
|
||||
zelle = self._cell(row, "Merkmale")
|
||||
if zelle is None:
|
||||
continue
|
||||
soll = int(json.loads(zelle).get("Anzahl_Separator", 0))
|
||||
ist = separator_je_id.get(tid, 0)
|
||||
assert soll == ist, (
|
||||
f"TeileId {tid}: Anzahl_Separator={soll}, aber {ist} "
|
||||
f"Separator-Zeile(n) mit Zuordnung darauf gefunden"
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Klasse 4: Sivas-Export-Pruefung (foerderer_tests_sivas.csv)
|
||||
|
||||
Reference in New Issue
Block a user