Files
dxfmakros/doc/LispTests.md
T

9.4 KiB
Raw Blame History

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/DWG.
  2. Python (pytest + ezdxf): Validiert die Ergebnisse automatisch gegen erwartete Werte und optionale Referenzdaten.
  Python (pytest)              AutoLISP (BricsCAD)            Python (pytest)
  ===============              ====================           ===============
  Testfall-Definitionen   -->  Ausfuehrung der          -->   Validierung:
  als JSON bereitstellen       LISP-Funktionen                - JSON-Ergebnisse
                               + DXF/DWG + results.json       - DXF-Geometrie
                                                              - Referenz-Vergleich

Verzeichnisstruktur

tests/
├── alltests.json             # Zentrale Testregistry (welche Module + Speicherformat)
├── test_run_all.lsp          # C:SSG_RUN_ALL_TESTS - fuehrt alle Tests aus
├── test_kreisel.lsp          # C:TEST_KREISEL - Kreisel-Testrunner
├── test_foerderer.lsp        # C:TEST_FOERDERER - Variofoerderer-Testrunner
├── test_kseinaus.lsp         # C:TEST_KSEINAUS - KreiselEinAus-Testrunner
├── test_omniflo.lsp          # C:TEST_OMNIFLO - Omniflo-Testrunner
├── conftest.py               # pytest Fixtures
├── test_kreisel.py           # pytest Kreisel-Validierung
├── test_omniflo.py           # pytest Omniflo-Validierung
├── create_testbase.py        # Hilfsskript (optional, i.d.R. nicht benoetigt)
├── requirements.txt          # Python-Abhaengigkeiten (ezdxf, pytest)
├── testdata/                 # JSON-Testfall-Definitionen (versioniert)
│   ├── kreisel_tests.json
│   ├── foerderer_tests.json
│   └── omniflo_tests.json
├── reference/                # Abgenommene Referenzdaten (versioniert)
│   └── omniflo_export_reference.csv
└── output/                   # Generierte Ergebnisse (nicht in Git)
    ├── kreisel_results.json
    ├── kreisel_tests.dxf
    ├── foerderer_results.json
    ├── foerderer_tests.dwg
    ├── kseinaus_results.json
    ├── omniflo_results.json
    └── omniflo_tests.dxf

Testregistry (alltests.json)

Die Datei tests/alltests.json ist die zentrale Registry aller Testmodule. SSG_RUN_ALL_TESTS liest sie beim Start — die Testliste ist nicht hartcodiert.

[
  { "name": "kreisel",   "save": "dxf", "module": "KreiselInsert"   },
  { "name": "foerderer", "save": "dwg", "module": "VarioFoerderer"  },
  { "name": "kseinaus",  "save": null,  "module": "VarioFoerderer"  },
  { "name": "omniflo",   "save": "dxf", "module": "OmniModulInsert" }
]
Feld Typ Bedeutung
name String Basisname des Testmoduls (Pflicht)
save "dxf" / "dwg" / null Speicherformat der Zeichnung
module String LISP-Modul (wird von ssg-ensure geladen)

Aus dem name werden alle Dateinamen abgeleitet:

Element Schema Beispiel (kreisel)
LISP-Datei tests/test_<name>.lsp tests/test_kreisel.lsp
BricsCAD-Befehl TEST_<NAME> TEST_KREISEL
Export-Funktion <name>:export-results kreisel:export-results
JSON-Ergebnis output/<name>_results.json output/kreisel_results.json
DXF/DWG-Datei output/<name>_tests.dxf/.dwg output/kreisel_tests.dxf

Schritt 1: Testfaelle definieren (JSON)

Jedes Modul hat eine eigene JSON-Datei in tests/testdata/. Format: flaches JSON-Array (kompatibel mit omni:load-json). Kein Nesting, keine Wrapper-Objekte.

Kreisel-Format (kreisel_tests.json)

[
  {
    "id": "KR_Kreuz_Q1_0Grad",
    "function": "insert",
    "x": 500, "y": 500, "z": 2500,
    "abstand": 2000,
    "rotation": 0.0,
    "typ": "STANDARD",
    "expect_block_prefix": "KREISEL_",
    "expect_hoehe": "2500",
    "expect_kreiselart": "STANDARD"
  }
]

Felder:

  • id — Eindeutiger Testfall-Name
  • function"insert" oder "connect"
  • Eingabeparameter: x, y, z, abstand, rotation, typ
  • expect_* — Erwartete Ergebniswerte (fuer Python-Validierung)

Foerderer-Format (foerderer_tests.json)

[
  { "y_abstand": 400 },
  {
    "test_id": "VF_Auf_0",
    "richtung": "Auf",
    "deltaL": 7000,
    "deltaH": 0
  }
]
  • Erster Eintrag (ohne test_id): Konfiguration (y_abstand zwischen Foerderern)
  • Felder: test_id, richtung ("Auf" / "Ab"), deltaL, deltaH
  • Ergebnisstatus: GEBAUT, NICHT_GEBAUT, GEOMETRISCH_UNMOEGLICH

Omniflo-Format (omniflo_tests.json)

[
  {
    "id": "821104025",
    "type": "bogen",
    "sivasnr": "821104025",
    "x": 219.4, "y": 223.06,
    "hoehe": 2000,
    "drehung": 0.0,
    "description": "APB 110 R 550/22,5  84/522",
    "row": "Boegen 22.5"
  }
]

Schritt 2: LISP-Testrunner ausfuehren (BricsCAD)

Alle Tests auf einmal

(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp"))
SSG_RUN_ALL_TESTS

SSG_RUN_ALL_TESTS liest alltests.json und fuehrt fuer jedes Modul aus:

  1. Zeichnung leeren (ERASE ALL + PURGE x5)
  2. test_<name>.lsp laden und TEST_<NAME> ausfuehren
  3. JSON-Export: <name>:export-results aufrufen (immer)
  4. Zeichnung speichern gemaess save-Feld ("dxf", "dwg" oder kein Speichern)
  5. Bei Fehler: weiter mit naechstem Test (Fehlerisolation)

Einzeltest (z.B. nur Kreisel)

(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp"))
TEST_KREISEL
(kreisel:export-results (strcat (getenv "DXFMAKRO") "/tests/output"))

Ausgabe: results.json

[
  {
    "test_id": "KR_Kreuz_Q1_0Grad",
    "status": "GEBAUT",
    "block_name": "KREISEL_STANDARD",
    "insert_point": [500.0, 500.0, 2500.0],
    "rotation": 0.0,
    "actual_kreiselart": "STANDARD",
    "actual_hoehe": "2500"
  }
]

Schritt 3: Python-Validierung (pytest)

bin\run_tests.bat --runall

Oder einzelnes Testmodul:

bin\run_tests.bat --runall test_kreisel.py

test_kreisel.py

Klasse Prueft
TestKreiselAttributes Attribute (KREISELART, HOEHE), Block-Prefixe, Status
TestKreiselGeometry DXF-Bloecke, Positionen, Kreis-Radien (400mm)
TestKreiselReference Block-Anzahl und -Typen gegen Referenz-DXF

test_omniflo.py

Klasse Prueft
TestOmnifloExportUnit Mock-Export: Merkmale, Datentypen, Vollstaendigkeit (ohne BricsCAD)
TestOmnifloExportCSV CSV aus BricsCAD: Header, Spalten, JSON-Merkmale

Tests, deren Eingabedaten fehlen (kein BricsCAD-Lauf), werden automatisch uebersprungen (pytest.skip).

Schritt 4: Referenz-Management

# Aktuelle Ergebnisse als neue Referenz speichern
bin\run_tests.bat --set-as-reference

Kopiert alle Dateien aus output/ nach reference/. Nur bei bestandenen Tests verwenden.

Modulspezifische Testfaelle

Kreisel (kreisel_tests.json)

Test-ID Beschreibung Params
KR_Kreuz_Q1_0Grad Standard Kreisel, 0 Grad rot=0, z=2500, abstand=2000
KR_Kreuz_Q2_90Grad Standard Kreisel, 90 Grad rot=90, z=2500, abstand=3000
KR_Kreuz_Q3_180Grad Standard Kreisel, 180 Grad rot=180, z=2500, abstand=4000
KR_Kreuz_Q4_270Grad Standard Kreisel, 270 Grad rot=270, z=2500, abstand=5000
KR_Schraeg_Q1_30Grad Standard Kreisel, schraeg rot=30, z=3000, abstand=3000
KR_Pin_Q1_0Grad Pin-Kreisel, 0 Grad rot=0, typ=PIN, z=1500
KR_Pin_Q1_90Grad Pin-Kreisel, 90 Grad rot=90, typ=PIN, z=1500
KR_Pin_Q1_30Grad_Schraeg Pin-Kreisel, schraeg rot=30, typ=PIN, z=1500

Foerderer (foerderer_tests.json)

Test-ID Richtung deltaL deltaH
VF_Auf_0 Auf 7000 0
VF_Auf_1000 Auf 7000 1000
VF_Auf_2000 Auf 7000 2000
VF_Auf_3000 Auf 7000 3000
VF_Auf_4000 Auf 7000 4000
VF_Auf_5000 Auf 7000 5000
VF_Ab_0 Ab 7000 0 (GEOMETRISCH_UNMOEGLICH)
VF_Ab_1000 Ab 7000 1000
VF_Ab_2000 Ab 7000 2000
VF_Ab_3000 Ab 7000 3000
VF_Ab_4000 Ab 7000 4000
VF_Ab_5000 Ab 7000 5000

Omniflo (omniflo_tests.json)

Testfaelle basieren auf echten Sivas-Nummern (Boegen und Zusatzmodule). Beispiele: 821104025, 821104025+0_B10090, 821104025+0_B10091, ...

Umgebungsvariablen

Werden via bin\setenv.bat gesetzt. Fuer Tests relevant:

Variable Beschreibung
DXFMAKRO Projektwurzel
DXFM_TESTS tests/-Verzeichnis
DXFM_TESTDATA testdata/-Verzeichnis
DXFM_TESTOUT output/-Verzeichnis
DXFM_TESTREF reference/-Verzeichnis
DXFM_OMNIFLO Pfad zu Omniflo-DXF-Dateien

Abhaengigkeiten

Python (tests/requirements.txt)

ezdxf>=1.0
pytest>=7.0

AutoLISP

  • SSG_LIB muss geladen sein (Menue per _MENULOAD eingerichtet, siehe CLAUDE.md)
  • test_run_all.lsp laedt die einzelnen Testrunner automatisch

Neuen Test erstellen

  1. Testdaten: testdata/<modul>_tests.json erstellen (flaches JSON-Array)
  2. LISP-Testrunner: test_<modul>.lsp erstellen mit c:TEST_<MODUL> und <modul>:export-results
  3. Testregistry: Eintrag in alltests.json hinzufuegen
  4. Python-Validierung (optional): test_<modul>.py und Fixtures in conftest.py

Detailliertes Vorgehen und Codevorlagen: siehe tests/README.md.