From 909f780bf0f84322d47ee63ead080320b775162a Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Thu, 28 May 2026 17:31:11 +0200 Subject: [PATCH] =?UTF-8?q?Testkonzept=20f=C3=BCr=20unsere=20Lisp=20files?= =?UTF-8?q?=20=C3=BCberlegt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/LispTests.md | 273 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 doc/LispTests.md diff --git a/doc/LispTests.md b/doc/LispTests.md new file mode 100644 index 0000000..a2e372c --- /dev/null +++ b/doc/LispTests.md @@ -0,0 +1,273 @@ +# Testkonzept SSG_LIB - Hybrid AutoLISP + Python + +## Uebersicht + +Die SSG_LIB AutoLISP-Makros werden ueber einen zweistufigen Hybrid-Ansatz getestet: + +1. **AutoLISP** (in BricsCAD): Liest JSON-Testfaelle, fuehrt die Funktionen aus, + schreibt Ergebnisse als JSON und DXF. +2. **Python** (pytest + ezdxf): Validiert die Ergebnisse automatisch gegen + erwartete Werte und optionale Referenz-DXFs. + +``` + Python (pytest) AutoLISP (BricsCAD) Python (pytest) + =============== ==================== =============== + Testfall-Definitionen --> Ausfuehrung der --> Validierung: + als JSON bereitstellen LISP-Funktionen - JSON-Ergebnisse + + DXF + results.json - DXF-Geometrie + - Referenz-Vergleich +``` + +## Verzeichnisstruktur + +``` +tests/ +├── testdata/ # JSON-Testfall-Definitionen (versioniert) +│ ├── kreisel_tests.json +│ ├── vario_tests.json +│ └── omniflo_tests.json +├── reference/ # Abgenommene Referenz-DXFs (versioniert) +│ └── kreisel_ref.dxf +├── output/ # Generierte Ergebnisse (in .gitignore) +│ ├── kreisel_tests.dxf +│ └── kreisel_results.json +├── ssg_testrunner.lsp # LISP Test-Runner +├── conftest.py # pytest Fixtures +├── test_kreisel.py # pytest Kreisel-Validierung +├── test_vario.py # pytest Vario-Validierung +├── test_omniflo.py # pytest Omniflo-Validierung +└── requirements.txt # Python-Abhaengigkeiten (ezdxf, pytest) +``` + +## Schritt 1: Testfaelle definieren (JSON) + +Jedes Modul hat eine eigene JSON-Datei in `tests/testdata/`. Aufbau: + +```json +{ + "module": "Kreisel", + "version": "1.0", + "description": "ILS Kreisel Testfaelle", + "tests": [ + { + "id": "KR_Horiz_ObenUnten", + "function": "draw-module", + "params": { + "basepoint": [500.0, 5000.0, 2500.0], + "abstand": 4200.0, + "rotation": 270.0, + "attribs": { + "KREISELART": "STANDARD", + "NAME": "TEST_H_ObenUnten" + } + }, + "expect": { + "attributes": { + "KREISELART": "STANDARD", + "DREHUNG": "270", + "ABSTAND": "4200" + }, + "block_prefix": "KR_", + "min_entities": 6 + } + } + ] +} +``` + +### Felder + +| Feld | Beschreibung | +|---|---| +| `id` | Eindeutiger Testfall-Name | +| `function` | Aufzurufende LISP-Funktion | +| `params` | Uebergabewerte an die Funktion | +| `expect.attributes` | Erwartete Block-Attribute nach Ausfuehrung | +| `expect.block_prefix` | Erwartetes Praefix des erzeugten Block-Namens | +| `expect.min_entities` | Mindestanzahl Entities im erzeugten Block | + +## Schritt 2: LISP Test-Runner (ssg_testrunner.lsp) + +Der LISP Test-Runner liest die JSON-Testfaelle, fuehrt die Funktionen in +BricsCAD aus und schreibt die Ergebnisse. + +### Aufruf in BricsCAD + +``` +Command: TESTRUN "kreisel" +``` + +Der Befehl: +1. Liest `tests/testdata/kreisel_tests.json` +2. Erstellt eine neue leere Zeichnung +3. Fuehrt fuer jeden Testfall die angegebene Funktion mit den Parametern aus +4. Sammelt Ergebnisse: Block-Handle, tatsaechliche Attribute, Insertionspunkt +5. Schreibt `tests/output/kreisel_results.json` +6. Speichert die Zeichnung als `tests/output/kreisel_tests.dxf` + +### Ausgabe: results.json + +```json +[ + { + "test_id": "KR_Horiz_ObenUnten", + "status": "executed", + "block_handle": "A3F", + "block_name": "KR_STANDARD_01", + "insert_point": [500.0, 5000.0, 2500.0], + "rotation": 270.0, + "actual_attributes": { + "KREISELART": "STANDARD", + "DREHUNG": "270", + "ABSTAND": "4200", + "NAME": "TEST_H_ObenUnten" + } + } +] +``` + +## Schritt 3: Python-Validierung (pytest) + +Die Python-Tests lesen `results.json` und die erzeugte DXF-Datei und pruefen: + +### 3a. Attribut-Pruefung (results.json) + +Vergleicht `actual_attributes` aus results.json gegen `expect.attributes` +aus den Testdefinitionen. Keine BricsCAD-Instanz noetig. + +### 3b. Geometrie-Pruefung (ezdxf) + +Oeffnet die erzeugte DXF-Datei mit der Python-Bibliothek `ezdxf` und prueft: + +- **Block-Existenz**: Alle erwarteten Bloecke im Modelspace vorhanden +- **Entity-Anzahl**: Mindestanzahl Entities pro Block +- **Kreisradien**: AN8/SP8-Kreise haben korrekten Radius (400mm) +- **Linienlaengen**: Tangenten haben korrekte Laenge (= Abstand) +- **Layer-Zuordnung**: Entities auf korrektem Layer +- **Insertionspunkte**: Bloecke an erwarteter Position + +### 3c. Referenz-Vergleich + +Vergleicht die Ergebnis-DXF gegen eine abgenommene Referenz-DXF: + +- Gleiche Anzahl Bloecke im Modelspace +- Gleiche Block-Typen +- Gleiche Attributwerte + +## Schritt 4: Referenz-Management + +### Neue Referenz erstellen (erster Lauf oder nach Aenderung) + +```bash +# 1. Tests in BricsCAD ausfuehren +# Command: TESTRUN "kreisel" + +# 2. Ergebnis-DXF visuell pruefen (in BricsCAD oeffnen) + +# 3. Wenn OK: Als neue Referenz speichern +copy tests\output\kreisel_tests.dxf tests\reference\kreisel_ref.dxf +``` + +### Referenz aktualisieren + +Wenn sich die LISP-Logik aendert und die neuen Ergebnisse korrekt sind: + +```bash +# 1. Tests in BricsCAD ausfuehren +# 2. Ergebnis visuell pruefen +# 3. Python-Tests zeigen Referenz-Abweichung: +pytest tests/test_kreisel.py -v +# FAILED test_block_count_matches_reference - 6 != 5 + +# 4. Neue Referenz speichern +copy tests\output\kreisel_tests.dxf tests\reference\kreisel_ref.dxf + +# 5. Tests erneut ausfuehren - jetzt PASS +pytest tests/test_kreisel.py -v +``` + +## Ausfuehrung + +### Kompletter Testlauf + +```bash +# Umgebung setzen +bin\setenv.bat + +# 1. Testdaten-DXF erzeugen (Python, optional wenn Basis-DXF benoetigt) +python tests/create_testbase.py + +# 2. BricsCAD starten und Tests ausfuehren +# In BricsCAD: TESTRUN "kreisel" +# In BricsCAD: TESTRUN "vario" +# In BricsCAD: TESTRUN "omniflo" + +# 3. Python-Validierung +pytest tests/ -v +``` + +### Nur Python-Validierung (ohne BricsCAD) + +```bash +# Setzt voraus, dass output/ bereits erzeugt wurde +pytest tests/ -v +``` + +### Einzelnes Modul testen + +```bash +pytest tests/test_kreisel.py -v +``` + +## Umgebungsvariablen + +| Variable | Pfad | Beschreibung | +|---|---|---| +| `DXFM_TESTS` | `/tests` | Test-Wurzelverzeichnis | +| `DXFM_TESTDATA` | `/tests/testdata` | JSON-Testdefinitionen | +| `DXFM_TESTOUT` | `/tests/output` | Generierte Ergebnisse | +| `DXFM_TESTREF` | `/tests/reference` | Abgenommene Referenzen | + +## Abhaengigkeiten + +### Python (tests/requirements.txt) + +``` +ezdxf>=1.0 +pytest>=7.0 +``` + +### AutoLISP + +- SSG_LIB muss geladen sein (ssg_load.lsp) +- `ssg_testrunner.lsp` wird manuell oder via on_start geladen + +## Modulspezifische Testfaelle + +### Kreisel (kreisel_tests.json) + +| Test-ID | Beschreibung | Params | +|---|---|---| +| KR_Horiz_ObenUnten | Horizontaler Kreisel, oben nach unten | rot=270, art=STANDARD | +| KR_Horiz_UntenOben | Horizontaler Kreisel, unten nach oben | rot=90, art=PIN | +| KR_Vert_LinksRechts | Vertikaler Kreisel, links nach rechts | rot=0, art=PIN | +| KR_Vert_RechtsLinks | Vertikaler Kreisel, rechts nach links | rot=180, art=STANDARD | +| KR_Insert_Schraeg | Kreisel mit 10 Grad Drehung | rot=10, abstand=6000 | + +### Vario (vario_tests.json) + +| Test-ID | Beschreibung | Params | +|---|---|---| +| VF_Gerade_1Segment | Einzelnes gerades Segment | laenge=2000 | +| VF_Gerade_3Segmente | Drei gerade Segmente | laenge=6000 | +| VF_Gefaelle_Standard | Gefaellestrecke Standard | hoehe=500 | +| VF_Bogen_Links | Linksbogen | winkel=90 | +| VF_Bogen_Rechts | Rechtsbogen | winkel=-90 | + +### Omniflo (omniflo_tests.json) + +| Test-ID | Beschreibung | Params | +|---|---|---| +| OM_Bogen_90 | 90-Grad Bogen | winkel=90 | +| OM_Weiche_Links | Linksweiche | seite=L | +| OM_Weiche_Rechts | Rechtsweiche | seite=R |