Unit-Tests
Integriertes Unit-Test-Framework für TIA-Bausteine. Schreiben, ausführen und auswerten von Tests gegen eine laufende PLCSIM Advanced Instanz direkt in der App.
Voraussetzungen:
- Enterprise-Lizenz
- PLCSIM Advanced V3.0+ installiert (separate Siemens-Lizenz)
- Ein TIA-Projekt mit mindestens einer geöffneten SPS
Unit-Testing-Workspace öffnen
- Klicken Sie auf das Unit Testing-Symbol (Becherglas) in der Aktivitätsleiste ganz links
- Die Seitenleiste zeigt dann die zwei Unit-Testing-Ansichten:
- Test Suites — der Explorer-Baum der gefundenen
.tia-tests-Suiten, mit den Titelleisten-Aktionen New Test Suite, Refresh Test Suites, Run All Test Suites / Stop Test Run sowie einem Pro-Suite-Inline-Run Test Suite - Test Results — Live-Progress und Assertion-Details (Gesamt / Bestanden / Fehlgeschlagen / Fehler)
- Test Suites — der Explorer-Baum der gefundenen
- Eine Suite aus dem Baum öffnet sie als Test-Suite-Editor im Editorbereich in der Mitte. Der Editor zeigt dieselbe Suite in drei umschaltbaren Ansichten – Visual, JSON und SCL – und bietet zusätzlich eine Open as JSON Text-Ausweichoption; seine Toolbar bietet Save, Open as JSON Text, Validate und Add Test Case.
Test Explorer
Der Test Explorer scannt automatisch den Ordner {WorkingDirectory}/.tia-tests/ und zeigt jede .json-Datei als Suite-Knoten mit ihren Test-Cases als Kinder.
Status-Icons (beim App-Start aus SQLite geladen):
- ✓ Bestanden — grünes Häkchen, Test erfolgreich im letzten Lauf
- ✗ Fehlgeschlagen — rotes Kreuz, Test fehlgeschlagen
- ⚠ Fehler — orange Warnung, Test hatte einen Fehler (Exception, Timeout, S7-Fehler)
- ⊘ Übersprungen — grauer durchgestrichener Kreis, Test wurde aus dem letzten Lauf herausgefiltert
- ○ Nicht ausgeführt — grauer leerer Kreis, kein gespeichertes Ergebnis
Interaktionen:
| Aktion | Ergebnis |
|---|---|
| Doppelklick auf Suite (oder auswählen und Enter drücken) | Öffnet die Suite als Test-Suite-Editor im Editorbereich |
| Suite überfahren → Inline-Run Test Suite | Führt nur diese Suite aus |
| Run All Test Suites (Titelleiste der Ansicht) | Führt alle sichtbaren Suites sequentiell aus |
| Stop Test Run (Titelleiste, während ein Lauf läuft) | Bricht den laufenden Run am nächsten sicheren Punkt ab |
| New Test Suite / Refresh Test Suites (Titelleiste) | Eine neue Suite anlegen oder den .tia-tests/-Ordner neu einlesen |
Geplant für den In-App-Arbeitsbereich. Ein Suchfeld zum Filtern der Suites nach Namen, ein
✗ Fehler-Toggle, eine Pro-Case-Run Test-Aktion und eine Nur betroffene ausführen-Aktion (nur Suites erneut laufen lassen, deren zugrundeliegender Baustein sich geändert hat) sind geplant. Heute stehen Einzel-Suite- und Alle-Suites-Läufe wie oben zur Verfügung; auf der Kommandozeile führttia-test-runner run --rerun-affectedbereits nur die Suites aus, deren zugrundeliegender Baustein sich geändert hat (siehe CI/CD-Integration).
Geplant — Block-Change-Badge. Ein kleiner oranger Punkt neben einer Suite, deren zugrundeliegender PLC-Baustein sich seit ihrem letzten Lauf geändert hat, mit dem Tooltip „Baustein seit letztem Lauf geändert", ist für die Test-Suites-Ansicht geplant.
Testfall-Metadaten
Jeder Testfall im visuellen Editor einer Suite hat einen aufklappbaren Metadaten-Bereich (standardmässig zugeklappt, unterhalb der Variable-Watch-Liste). Klick auf den Bereichs-Header expandiert ihn und gibt folgende Felder pro Case zur Bearbeitung frei:
| Feld | Zweck |
|---|---|
| Reihenfolge | Numerische Lauf-Reihenfolge. Leer lassen, um die natürliche Reihenfolge in der Suite zu behalten |
| Tags | Kommagetrennte Labels (z. B. safety, regression) für Filter in HTML-Reports |
| Priorität | Niedrig / Normal / Hoch / Kritisch. Steuert Report-Sortierung |
| Verantwortlicher | Freitext-Verantwortlicher (Team-Name, E-Mail usw.) |
| Anforderungen | Kommagetrennte Anforderungs-IDs (z. B. REQ-123, REQ-456) für Traceability |
Schema-Validierungs-Issues, die einen bestimmten Testfall betreffen (etwa eine ungültige Priorität), werden in einem roten Panel direkt im Metadaten-Bereich des betroffenen Cases angezeigt. Issues, die die Suite als Ganzes betreffen, erscheinen weiterhin im Suite-Validierungs-Banner. Alle Änderungen werden zusammen mit der Suite automatisch gespeichert. Suites aus früheren Versionen laden mit leeren Metadaten-Defaults — keine Migration nötig.
Live-Progress während eines Laufs
Während ein Test läuft zeigt der Workspace:
- Statusleiste: Eine Fortschrittsanzeige signalisiert, dass der Lauf läuft (z.B. „Running '<Suite>'…"), während der Runner seine Phasen abarbeitet — PLCSIM-Instanz erstellen, kompilieren, verbinden, jeden Case ausführen
- Test-Suites-Ansicht: Status-Icons werden live pro Test-Case aktualisiert (Pass/Fail erscheinen während der Lauf läuft)
- Test-Results-Ansicht: Die Test-Case-Liste füllt sich inkrementell mit jedem abgeschlossenen Test
- Stop Test Run: Bricht den laufenden Run am nächsten sicheren Punkt ab (S7-Verbindung und PLCSIM-Instanz werden immer aufgeräumt)
Ergebnis-Panel
Nach einem Lauf zeigt das Ergebnis-Panel:
- Zusammenfassung: Zähler für Gesamt / Bestanden / Fehlgeschlagen / Fehler
- Test-Case-Liste: Jeder Case mit Status-Icon und Name; ein fehlgeschlagener Case zeigt zusätzlich seine Fehlermeldung
- Detail-Grid (pro Case): Alle Assertions mit Variable, Operator, Erwartet, Tatsächlich, ✓/✗
Geplant — Variablenverlauf-Diagramm. Ein In-App-Diagramm, das zeigt, wie sich jede Watch-Variable Zyklus für Zyklus während des Laufs verändert hat (mit Pro-Variable-Checkbox-Legende und Hover-Fadenkreuz), ist für die Test-Results-Ansicht geplant. Heute werden die
watch-Daten erfasst und als Zeitreihen-Chart in den HTML-Berichten des Kommandozeilen-Werkzeugstia-test-runnergerendert (siehe CI/CD-Integration).
Um Watch-Daten zu erfassen, füge ein "watch": ["Var1", "Var2"]-Array zu einem Testfall in der Suite-JSON hinzu und setze "cycles" größer als 1. Das Sampling ist pro Testfall auf 100.000 Zyklen gedeckelt.
Test-Ergebnisse werden in %LocalAppData%\AnyAutomation Studio\db\test_results.db persistiert — sie überleben App-Neustarts und erscheinen automatisch wieder in der Test-Suites-Ansicht.
Lauf-Historie
Geplant für den In-App-Arbeitsbereich. Lauf-Historie, Runs vergleichen und Trend sind unten als vollständiger Funktionsumfang beschrieben. Heute werden sie vom Kommandozeilen-Werkzeug
tia-test-runnererzeugt (HTML-/CSV-Berichte — siehe CI/CD-Integration); die eigenen In-App-Ansichten sind geplant. Die In-App-Ansicht Test Results zeigt bereits die Assertion-Details des jüngsten Laufs.
Die Lauf-Historie-Ansicht listet jeden Lauf, der jemals in die Datenbank geschrieben wurde — unabhängig davon, welche Suite ausgeführt wurde.
- Spalten: Status-Icon, Gestartet (Lokalzeit), Dauer, Bestanden / Fehlgeschlagen / Fehler / Übersprungen, Suite, SPS, Hostname, TIA-Version
- Status-Icon: ✓ grün, wenn alle Cases bestanden; ✗ rot bei beliebigem Fehler oder Fehlschlag
- Filterfeld: Filtert die Liste clientseitig nach Hostname, Suite-Name, SPS oder Baustein-Name (case-insensitive)
- Aktualisieren:
F5lädt die Liste neu (oder per Eintrag im Kontextmenü)
Kontextmenü-Aktionen (Rechtsklick auf einen Lauf):
| Aktion | Ergebnis |
|---|---|
| Ergebnisse öffnen | Lädt diesen Lauf in die Test Results-Ansicht zur Detail-Ansicht |
| Vergleichen mit… | Markiert diesen Lauf als Baseline und öffnet den Dialog Lauf zum Vergleichen wählen. Nach Auswahl eines zweiten Laufs aktiviert sich die Runs vergleichen-Ansicht mit dem Diff |
| Lauf löschen | Entfernt den Lauf-Eintrag samt aller Testfälle und Provenance-Metadaten dauerhaft. Block-Hashes bleiben erhalten, damit Block-Change-Vergleiche weiterfunktionieren |
| HTML exportieren | Rendert den Lauf als eigenständige HTML-Report-Datei (<run-id>.html) im selben Stil wie das In-App-Ergebnis-Panel |
| Manifest öffnen | Öffnet das SHA-256-Integrity-Manifest des Laufs (sofern eines beim Report-Render erzeugt wurde) |
Die Liste zeigt standardmäßig die jüngsten 100 Läufe in absteigender Reihenfolge. Provenance-Werte wie Hostname und TIA-Version stammen aus den Metadaten, die beim Run-Start aufgezeichnet werden; der Projektpfad selbst wird nie im Klartext gespeichert — nur als irreversibler SHA-256-Hash, sodass Läufe maschinenübergreifend korreliert werden können, ohne Workspace-Pfade zu leaken.
Runs vergleichen
Die Runs vergleichen-Ansicht wird bei Bedarf über Vergleichen mit… in der Lauf-Historie geöffnet — Sie wählen einen Baseline-Lauf, der Auswahl-Dialog fragt nach einem zweiten Lauf, und die Runs-vergleichen-Ansicht aktiviert sich mit dem Diff-Ergebnis.
- Header: Baseline-/Aktuell-Run-IDs nebeneinander, Tauschen-Button kehrt den Vergleich um, HTML exportieren schreibt den Diff als eigenständigen HTML-Bericht (derselbe Renderer, den der Befehl
tia-test-runner compareverwendet) - Summary-Pills: Fünf farb-kodierte Zähler — Regressionen (rot), Behoben (grün), Neu (blau), Entfernt (grau), Stabil (gedämpft). Stabil zählt nur Still-Passing- und Unchanged-Cases; Still-Failing-Cases bleiben als Warnung markiert, NICHT als stabil
- Filter-Leiste: Fünf Radio-Buttons (Alle / Regressionen / Behoben / Neu / Entfernt) reduzieren die Case-Liste in-place
- Case-Zeilen: Jede Zeile zeigt einen farbigen Bullet-Punkt (rot / grün / blau / grau / orange) plus
<Suite> / <Case>, die Fehlermeldung (sofern vorhanden), das ChangeKind-Label und das Duration-Delta gegenüber der Baseline (+12 ms/−5 ms)
Der Auswahl-Dialog listet die jüngsten 100 Läufe abzüglich der gewählten Baseline, sortiert neueste-zuerst. Doppelklick auf eine Zeile oder Klick auf OK übernimmt die Auswahl; Abbrechen schließt den Dialog ohne Vergleichswechsel.
Trend
Die Trend-Ansicht visualisiert Erfolgsquote, Dauer und Pro-Case-Status über die Zeit anhand der historischen Läufe in der Datenbank.
- Filter-Leiste (Reihe 1): PLC-Name (Pflicht), Suite-Name (optional — beschränkt das Dauer-Diagramm), Case-Name (optional — beschränkt die Heatmap)
- Filter-Leiste (Reihe 2): Von-/Bis-Kalender-Picker (Picker leeren entfernt die Schranke), Letzte 30 Tage / Letzte 90 Tage-Schnell-Buttons, Aktualisieren für Re-Query, CSV exportieren schreibt den aktuellen Trend in eine CSV-Datei (derselbe Export, den der Befehl
tia-test-runner trenderzeugt) - Erfolgsquoten-Diagramm: Time-Series-Scatter, X = Lauf-Startzeit, Y = Erfolgsquote in %. Sichtbar sobald die Project-Query mindestens einen Punkt liefert; sonst "Keine Daten".
- Dauer-Diagramm: Time-Series-Scatter, X = Lauf-Startzeit, Y = Suite-Dauer in Sekunden. Erfordert einen Suite-Namen; sonst "Keine Daten".
- Case-Heatmap: Cells fließen links-nach-rechts, eine pro Lauf, farb-kodiert nach Status (grün = Pass, rot = Fail, orange = Error, grau = Skipped) plus Glyphe (
✓/✗/!/—) für Barrierefreiheit. Hover über eine Cell zeigt den Lauf-Zeitstempel. Erfordert sowohl Suite- als auch Case-Name; sonst "Keine Daten".
Schlägt die Project-Trend-Query fehl (DB offline, beschädigter Bereich), erscheint die Fehlermeldung im unteren Banner. Suite- und Case-Query-Fehler zeigen einen eigenen roten Banner direkt über dem betroffenen Diagramm — die anderen Diagramme rendern normal weiter.
Baustein-Analyse (vor dem Testen)
Beim Öffnen einer Suite liest AnyAutomation Studio das Baustein-Interface aus dem TIA-Projekt, damit der Editor die echten Parameternamen und -typen kennt und die Inputs- und Assertions-Grids dagegen validieren können.
Geplant für den In-App-Arbeitsbereich. Eine eigene Analyse-Oberfläche mit den Bereichen Interface, Boundary Values und Dependencies ist geplant. Die Daten, die sie zusammenfassen würde:
- Interface: Alle Baustein-Parameter (Input, Output, InOut, Static, Temp) mit Typen und Defaultwerten
- Boundary Values: Automatisch generierte Min/Max/Null/Eins-Werte pro Parametertyp
- Dependencies: Aufgerufene Bausteine, referenzierte DBs, referenzierte UDTs
Neue Test-Suite erstellen
- Klicken Sie in der Titelleiste der Test-Suites-Ansicht auf New Test Suite (oder starten Sie den Befehl über die Befehlspalette)
- Beantworten Sie die drei nacheinander erscheinenden Eingaben: den Suite-Namen, den getesteten Baustein und den PLC-Namen
- Die neue Suite wird als
<projectDir>/.tia-tests/{name}.jsongeschrieben und erscheint in der Test-Suites-Ansicht - Der Test-Suite-Editor öffnet sich mit einem Start-Testfall, der
arrange/act/assertions/watchzeigt, damit Sie sehen, wie die Teile zusammenpassen. Das Baustein-Interface wird aus dem TIA-Projekt gelesen, sodass die Inputs- und Assertions-Grids gegen die echten Parameternamen validieren. Ersetzen Sie Platzhalterwerte stets durch echte Namen, bevor Sie den Runner auf Hardware richten. - Nutzen Sie den Visual-Modus (Form-basiert, Master-Detail) um Test-Cases via Felder und Grids hinzuzufügen / löschen / duplizieren — Name, Beschreibung, Zyklen, Tags, Priorität + Arrange-Inputs-Grid + Assertions-Grid + Watch-Liste. Über Open as JSON Text können Sie jederzeit das rohe JSON bearbeiten. Die SCL-Ansicht zeigt den generierten SCL-Testcode und ist ebenfalls bearbeitbar (siehe Suites und Testfälle verwalten)
- Save (
Strg+S) klicken um Ihre Änderungen zu speichern
Suite über das JSON-name-Feld umbenennen
Wenn Sie das name-Feld oben in der Suite-JSON ändern und Save drücken, wird die Datei auf der Disk passend umbenannt — {neuerName}.json — und der Editor-Titel aktualisiert sich im selben Schritt. Existiert bereits eine Suite mit dem neuen Namen im gleichen Ordner, bricht Save mit einer Fehlermeldung ab und lässt beide Dateien unverändert, damit Sie einen anderen Namen wählen können.
Das blockName-Feld ist davon unabhängig und identifiziert weiterhin den getesteten TIA-Baustein; ein Namens-Rename verändert es nicht.
Test-Suite-JSON-Schema
Jede .tia-tests/*.json-Datei folgt der gleichen Struktur. Top-Level-Felder:
| Feld | Typ | Pflicht | Zweck |
|---|---|---|---|
name | string | ja | Suite-Identifier (muss zum Dateinamen ohne .json passen) |
blockName | string | ja | Exakter TIA-Bausteinname (case-sensitive) |
plcName | string | ja | SPS-/CPU-Name im TIA-Projekt (z.B. PLC_1) |
config | object | ja | Verbindungs- + Transport-Einstellungen (siehe unten) |
testCases | array | ja | Ein Eintrag pro Test-Case (siehe unten) |
config (alle Felder optional, Defaults gezeigt):
| Feld | Default | Zweck |
|---|---|---|
cycles | 1 | Default-PLC-Zyklen pro Test-Case (überschreibbar pro Case via act.cycles) |
cycleWaitMs | 100 | Wartezeit zwischen Sample-Reads bei cycles > 1 |
timeoutMs | 5000 | Hard-Timeout pro Test-Case |
instanceDbName | "" | Instance-DB für Lese-/Schreibzugriff; leer → <blockName>_DB (Siemens-Konvention) |
preferFc | false | FC-Bausteine (ohne Instance-DB) tolerieren; setzen wenn das Ziel eine Function statt Function-Block ist |
transport | "s7CommPlus" | "s7CommPlus" für reale SPS / TCP-PLCSIM, "plcSimApi" für direkte PLCSIM-Tag-API |
s7IpAddress | 192.168.0.1 | S7-Verbindungsziel — wird nur verwendet wenn preparationMode = "external" (echte SPS). Bei PLCSIM-basierten Modi (userPreloaded, tiaTcpDownload) verbindet sich der Runner mit plcSimIp, unabhängig vom Transport |
s7Port | 102 | S7-ISO-on-TCP-Port. Der Standard 102 passt zu allen Siemens-Defaults — nur ändern, wenn die SPS auf einen abweichenden TCP-Port umkonfiguriert wurde |
s7User, s7PasswordKeyId | "" / null | Anmeldedaten-Referenz (Passwort liegt im Windows Credential Manager). Nur erforderlich wenn die SPS Benutzer-Authentifizierung erzwingt — die meisten Projekte lassen das leer |
plcSimInstanceName | "TiaUnitTest" | PLCSIM-Advanced-Instanzname. Wird von beiden Transports genutzt sobald preparationMode != "external" |
plcSimIp | "192.168.0.100" | PLCSIM-Virtual-Adapter-IP. Das ist das tatsächliche S7-Verbindungsziel bei s7CommPlus + userPreloaded/tiaTcpDownload — auf die IP setzen, die dem Siemens PLCSIM Virtual Ethernet Adapter zugewiesen wurde, nicht auf die Projekt-IP der SPS |
preparationMode | "userPreloaded" | userPreloaded (Default; setzt voraus dass die PLCSIM-Instanz bereits mit dem Projekt geladen läuft), tiaTcpDownload (compiliert + lädt herunter aus dem offenen TIA-Projekt — siehe Voraussetzungen unten), oder external (echte SPS; nutzt s7IpAddress) |
masterSecretPasswordKeyId | null | Projekt-Master-Secret-Passwort-Referenz. Nur bei tiaTcpDownload erforderlich wenn das TIA-Projekt vertraulichen Konfig-Schutz nutzt. Passwort liegt im Windows Credential Manager |
autoConnectS7 | true | S7 vor Run-Start automatisch verbinden. Nur in fortgeschrittenen Setups auf false setzen, in denen ein anderer Client (WinCC, custom HMI) die Session bereits hält und der Runner durch diese Session lesen/schreiben soll |
keepInstanceAfterRun | false | PLCSIM-Instanz nach dem Run weiterlaufen lassen. Wirkt ausschliesslich in tiaTcpDownload-Modus — userPreloaded und external verwalten die Instanz nie |
Jeder Eintrag in testCases:
| Feld | Typ | Pflicht | Zweck |
|---|---|---|---|
name | string | ja | PascalCase-Szenario-Name (z.B. Start_FromIdle_Runs) |
description | string | nein | Ein-Satz-Was-und-Warum |
arrange.inputs | object | ja | { "MemberName": value, … } — wird vor Act in die DB geschrieben |
act.cycles | int | nein (Default config.cycles) | PLC-Zyklen zwischen Arrange und Assert; muss > 1 sein, damit watch[] feuert. Schließt sich gegenseitig mit act.steps aus (das oneOf im Schema lehnt beides am selben act ab) |
act.timeoutMs | int | nein (Default config.timeoutMs) | Per-Case-Timeout. Deckt die gesamte steps-Sequenz ab, wenn steps gesetzt ist |
act.steps | array | nein | Optionale geordnete Sequenz aus write / wait / assert-Schritten, die zwischen Arrange und den Top-Level-assertions läuft. Siehe Mehrstufige Schritte unten. Schließt sich gegenseitig mit act.cycles aus |
assertions | array | ja | [ { "variable": "X", "operator": "equal", "expected": v, "tolerance": t? }, … ] |
watch | string[] | nein | Variablen die einmal pro Zyklus während Act gesampled werden → Zeitreihen-Chart in den HTML-Berichten |
tags | string[] | nein | Frei wählbare Labels |
priority | string | nein | "low" / "normal" (Default) / "high" |
requirements | string[] | nein | Traceability-Links |
order | int | nein | Stabile Sortier-Reihenfolge in der UI |
Unterstützte operator-Werte: equal, notEqual, greaterThan, lessThan, inRange (erwartet expected: [min, max]), isTrue, isFalse. tolerance greift nur bei Real/LReal mit equal/notEqual (Default 0.0001). expected ist vom Schema für jede Assertion erforderlich (für isTrue/isFalse einen beliebigen Wert setzen — false, true, 0 — der Runner ignoriert ihn dort).
Sicherheit — Beispielwerte sind Platzhalter. Wenn der Editor keine echten Input-/Output-Namen aus dem Baustein-Interface ableiten kann, nutzt das Beispiel sichere Defaults (
Enable: false,Running: false), damit ein Klick auf Run keine Motoren, Ventile oder andere Outputs auf realer Hardware aktivieren kann. Vor jedem Lauf gegen eine reale SPS jedenarrange.inputs-Wert und jede Assertion prüfen.
Wichtig —
watch[]ist das Diagnose-Array des Test-Cases, NICHT die TIA-Beobachtungstabelle. Variablen inwatchwerden einmal pro PLC-Zyklus während der Act-Phase gesampled (sofernact.cycles > 1) und in den HTML-Berichten als Zeitreihen-Chart gerendert. Das ist unabhängig von TIA Portals externer Beobachtungstabelle oder einer OPC-UA-Subscription.
Vollständiges Beispiel
Eine vollständige minimale Suite mit einem Test-Case der jeden Block nutzt und watch[] verwendet:
{
"name": "FB_Motor_Tests",
"blockName": "FB_Motor",
"plcName": "PLC_1",
"config": {
"cycles": 1,
"timeoutMs": 5000,
"instanceDbName": "FB_Motor_DB",
"transport": "s7CommPlus",
"s7IpAddress": "192.168.0.1",
"s7Port": 102,
"autoConnectS7": true,
"preparationMode": "userPreloaded"
},
"testCases": [
{
"name": "Start_FromIdle_RunsWithinThreeCycles",
"description": "Prüft dass Run nach gesetztem StartCmd hochgeht; watch zeigt Verlauf.",
"arrange": {
"inputs": {
"StartCmd": true,
"Reset": false,
"Speed": 50.0
}
},
"act": { "cycles": 5 },
"assertions": [
{ "variable": "Run", "operator": "equal", "expected": true },
{ "variable": "Speed_Act", "operator": "inRange", "expected": [49.5, 50.5] },
{ "variable": "Error", "operator": "isFalse", "expected": false }
],
"watch": ["Run", "Speed_Act", "StartCmd"],
"tags": ["happy-path", "smoke"],
"priority": "normal"
}
]
}
Nach dem Run zeigt die Test-Results-Ansicht pass/fail pro Assertion, und der HTML-Bericht rendert ein Zeitreihen-Chart für die drei watch-Variablen über die 5 Zyklen. Um weitere Variablen zu einem bestehenden Case hinzuzufügen: Variablennamen ans watch-Array anhängen und act.cycles auf eine sinnvolle Zahl erhöhen (3-10 ist typisch).
Mehrstufige Schritte (act.steps)
Wenn ein einzelnes Arrange-dann-Assert nicht ausreicht — z.B. Reset → warten → Start → warten → prüfen — act.steps statt act.cycles verwenden. Drei Step-Typen:
type | Pflichtfelder | Effekt |
|---|---|---|
"write" | inputs (Object, gleiche Form wie arrange.inputs) | Schreibt die gelisteten Members additiv auf den aktuellen DB-Zustand. Nicht gelistete Members behalten ihren Wert. |
"wait" | ms (int, 0..3 600 000) | Async-Delay. Die SPS zykelt weiter. Wenn watch[] nicht leer ist und config.cycleWaitMs > 0, werden beobachtete Variablen alle config.cycleWaitMs ms während des Wait-Fensters gesampled. |
"assert" | assertions (Array, gleiche Form wie Top-Level-assertions) | Per-Step-Checkpoint. Ein Fehler bricht den Case sofort ab und meldet Step <N> (assert): <Grund> (1-basiert). |
Reihenfolge der Operationen:
arrange.inputswird einmal am Case-Start geschrieben (nicht zwischen Steps wiederholt).- Jeder Eintrag in
stepsläuft in Deklarationsreihenfolge. - Nach dem letzten Step läuft das Top-Level-
assertions[]als Final-Gate. Per-Step-Asserts und Top-Level-Asserts sind unabhängig — beide müssen passen. Das Schema verlangtminItems: 1auf Top-Level-assertions, also mindestens eine triviale Top-Level-Assertion authoren auch wenn man primär per-Step-Asserts nutzt. watch[]sampled durchgehend während jedemwait-Step (unter den oben genannten Bedingungen); das Time-Series-Chart annotiert Step-Grenzen.
Caps (vom Runner erzwungen):
| Limit | Wert |
|---|---|
| Steps pro Case | 1024 |
Inputs pro write-Step | 256 |
Assertions pro assert-Step | 256 |
wait.ms | 0..3 600 000 (1 Stunde) |
Visual-Editor: Die Case-Detail-Ansicht zeigt einen Steps (optional)-Bereich mit + Write, + Wait, + Assert-Buttons zum Anhängen, per-Step ↑ / ↓-Buttons zum Umsortieren, und − zum Entfernen. Der Editor lässt cycles automatisch im serialisierten JSON weg, sobald der Steps-Bereich nicht leer ist (das Schema lehnt die cycles + steps-Kombination ab, der Editor produziert sie also nie).
Backwards-Kompatibilität: Ein Case ohne steps läuft den bestehenden Single-Phase-cycles-Pfad ohne Verhaltensänderung. Ältere Suites brauchen keine Migration.
Vollständiges Beispiel — getakteter Motor-Start
StartCmd wird nach einem 500 ms langen Reset-Fenster gesetzt, dann warten wir 2 s bis der FB Run erreicht, plus eine abschließende Speed-Prüfung.
{
"name": "MotorStart_ReachesRun",
"description": "Reset, warten, Start, warten, Run prüfen.",
"arrange": { "inputs": { "Enable": true } },
"act": {
"timeoutMs": 10000,
"steps": [
{ "type": "write", "inputs": { "Reset": true } },
{ "type": "wait", "ms": 500 },
{ "type": "write", "inputs": { "Reset": false, "StartCmd": true } },
{ "type": "wait", "ms": 2000 },
{ "type": "assert", "assertions": [
{ "variable": "Run", "operator": "isTrue", "expected": true }
]
}
]
},
"assertions": [
{ "variable": "Speed_Act", "operator": "greaterThan", "expected": 1000 }
],
"watch": ["Run", "Speed_Act"]
}
Wenn der Per-Step-assert fehlschlägt (z.B. Run ist nicht innerhalb von 2 s true geworden), gibt der Runner Step 5 (assert): variable Run is not true aus und bricht den Case ab. Wenn die Per-Step-Asserts alle passen aber das Top-Level-Speed_Act > 1000 fehlschlägt, scheitert der Case mit der Top-Level-Assertion-Message.
Im Zweifel: zuerst einen einfachen Arrange + cycles ≥ N + Assert-Case schreiben. Erst in eine steps-Sequenz konvertieren wenn die einfache Form das Timing nicht ausdrücken kann, von dem der Test wirklich abhängt.
Vorhandene Suite öffnen
- Aus der Test-Suites-Ansicht: Doppelklick auf die Suite im Baum (sie öffnet sich im Test-Suite-Editor)
- Aus Schnell öffnen:
Strg+Pdrücken und den Suite-Dateinamen unter.tia-tests/eingeben
Wo werden Test-Suiten gespeichert?
Test-Suiten liegen in einem versteckten Ordner namens .tia-tests direkt neben Ihrer TIA-Projektdatei (*.ap21, *.ap20, …). Der AI-Assistent schreibt in denselben Ordner. Wenn noch kein TIA-Projekt geladen ist, zeigt die Test-Suites-Ansicht "Kein TIA-Projekt verbunden" — bitte erst ein Projekt verbinden.
Die KI kann diese Test-Suite-Dateien direkt aus dem Chat heraus lesen, auflisten und bearbeiten.
Tests ausführen
- Sicherstellen dass PLCSIM Advanced V3.0+ installiert ist
- Suite aus der Test-Suites-Ansicht öffnen
- Ausführen: die Pro-Suite-Inline-Aktion Run Test Suite in der Test-Suites-Ansicht verwenden, Run All Test Suites aus der Titelleiste der Ansicht, oder eine Rechtsklick-Kontextmenü-Aktion
- Den Live-Progress in der Statusleiste und der Test-Results-Ansicht verfolgen
- Nach dem Lauf aktualisieren sich die Status-Icons in der Test-Suites-Ansicht und Ergebnisse werden in SQLite gespeichert
Der Runner erledigt automatisch:
- Erstellt eine PLCSIM Advanced Instanz (Name konfigurierbar in der Suite-JSON)
- Schaltet sie ein und kompiliert das aktuelle SPS-Projekt
- Verbindet einen S7-Client mit der Instanz
- Schreibt die Test-Inputs, wartet die konfigurierten Zyklen, liest die Outputs, evaluiert die Assertions
- Räumt die S7-Verbindung auf und deregistriert die Instanz
Transport auswählen
Der Transport entscheidet, wie Test-Reads und -Writes zwischen AnyAutomation Studio und der PLC übertragen werden. Sie setzen ihn in der Suite-JSON über config.transport (siehe Schema oben):
- PLCSim Advanced (
plcSimApi) — Direkter Zugriff über die Siemens-PLCSim-API, schneller und ohne aktive S7-Session. Ideal für reine Simulator-Tests. - S7 Nativ (
s7CommPlus) — Nutzt den S7-Communication-Treiber über TCP/IP. Wählen Sie diese Option für Tests gegen echte Hardware (in Kombination mit dem Vorbereitungsmodus Reale PLC) oder gegen PLCSim über den virtuellen Ethernet-Adapter mit Benutzerauthentifizierung. Gleiches Protokoll wie in der PLC-Online-Ansicht.
Jede Suite wird unabhängig konfiguriert. Bei S7 Nativ hat die Suite eigene IP, TCP-Port, Benutzername und Passwort — kein Cross-Feature-Lookup aus der PLC-Online-Ansicht. Rack und Slot sind nicht konfigurierbar: S7-1200/1500 verbinden sich über das S7CommPlus-Protokoll mit fixem Routing-Handshake, und TLS ist auf jeder Verbindung Pflicht — beides erledigt der Transport.
Geplant für den In-App-Arbeitsbereich. Ein Verbindungseinstellungen-Dialog, der diese
config-Werte über ein Formular bearbeitet, ist geplant. Heute bearbeiten Sie sie direkt in der Suite-JSON (Open as JSON Text im Test-Suite-Editor).
Simulation-Arbeitsbereich
Geplant für den In-App-Arbeitsbereich. Eine eigene Simulation-Ansicht zur Verwaltung von PLCSim-Advanced-Instanzen direkt in AnyAutomation Studio ist geplant. Die Fähigkeiten, die sie bereitstellen würde, sind unten beschrieben.
Eine Simulation-Ansicht zur Verwaltung von PLCSim-Advanced-Instanzen würde zeigen:
- API-Version, Online-Zugriffsmodus (PLCSim / TCP/IP einzeln / TCP/IP mehrfach), Strict-Motion-Timing-Toggle und Runtime-Manager-Port.
- Eine Virtueller Adapter-Zeile mit dauerhaftem Status des Siemens PLCSIM Virtual Ethernet Adapters (Bereit / APIPA / Deaktiviert / Nicht installiert / Keine IPv4), seiner IPv4-Adresse und einem Refresh-Button. Wenn der Adapter im 169.254.x.y-APIPA-Bereich hängt, werden Downloads unzuverlässig — weisen Sie ihm in den Windows-Netzwerkeinstellungen eine statische IPv4-Adresse zu.
- Jede registrierte PLCSim-Instanz mit Inline-Buttons: Einschalten, Run, Stop, Memory-Reset, Ausschalten, Einstellungen, Netzwerk, Löschen. Jede Zeile zeigt die konfigurierte IP-Adresse; hat die Instanz mehrere Schnittstellen mit einer IP, werden diese als
X1: 192.168.0.1, X2: 10.0.0.5aufgelistet. - Eine TIA-PLC-ComboBox pro Instanz-Card: Wählen Sie die TIA-Portal-PLC, die der Instanz zugrunde liegt. Nötig, sobald die PLCSim-Instanz mit einem Snapshot beladen wurde, der aus einer anderen TIA-PLC kompiliert wurde als unter der die Instanz registriert ist (Beispiel: eine Instanz mit Namen
PLC_2, die aber das Programm ausPLC_1enthält). Ohne explizite Wahl gleicht die App per Name ab und greift auf die einzige PLC im Projekt zurück, wenn nur eine vorhanden ist — ausreichend für die meisten Setups, liefert aber einen leeren Tag-Baum, wenn die Namen nicht übereinstimmen. Die Auswahl wird pro Instanz gemerkt. - Einen Neue Instanz-Button, der nach Name und CPU-Typ fragt.
- Ein Tag-Browser-Panel, das sich mit jeder Instanz verbinden und alle Tags des laufenden Programms anzeigen kann — filterbar nach Namensuche, Bereich (Eingang / Ausgang / Merker / Datenbaustein) und Datentyp. Auto-Refresh kann für Live-Wertebeobachtung aktiviert werden. Jeder schreibbare Tag hat einen Bleistift-Button, der einen typ-spezifischen Write-Dialog öffnet (Schalter für Bool, numerische Eingabe mit passendem Bereich für Ganzzahlen und Gleitkomma, Ein-Zeichen-Feld für Char/WChar). String-Tags sind read-only. Struct-Tags und Array-Tags werden mit ihren inneren Membern und Elementen als ausklappbare Zeilen aufgelistet, sodass einzelne Felder wie
OUT[5]oderDI10.Channeldirekt durchsucht, beobachtet und geschrieben werden können; die Toolbar-Buttons Alle ausklappen und Alle einklappen schalten den gesamten Baum auf einmal um. Strukturierte Eingangs-/Ausgangs-Tags, deren Layout aus einer Projekt-Typdefinition stammt (zum Beispiel einPNPN-Block an%I0.0, deklariert alsArray[0..63] of Byte), klappen in benannte Member-Zeilen auf, sobald die App mit dem TIA-Portal-Projekt verbunden ist, das sie definiert — sodassIN.PNPN[12]aus demselben Dialog beschrieben werden kann, der auch den Rest des Baums verarbeitet. - Eine Gespeicherte Instanzen-Sektion am unteren Rand, die jede PLCSim-Advanced-Instanz auflistet, die auf der virtuellen SIMATIC Memory Card persistiert ist. Neben der Überschrift zeigt ein Zähler die Gesamtzahl gespeicherter Instanzen; die Liste zeigt maximal drei Zeilen gleichzeitig und scrollt bei mehr, damit der Simulationsbereich darüber sichtbar bleibt. Klicken Sie Laden, um eine solche Instanz erneut zu registrieren und fortzuführen — PLCSim übernimmt automatisch den gespeicherten CPU-Typ, das E/A-Abbild und das Programm. Klicken Sie Löschen (mit Bestätigung), um den persistierten Ordner zu entfernen.
Die Ansichts-Auswahl würde zwischen Sitzungen gemerkt, und der Wechsel behält alle geöffneten Suite-Editoren.
PLCSIM-Vorbereitungsmodus
Der Vorbereitungsmodus steuert, wie der Runner das Projekt vor dem Testlauf bereitstellt. Er wird in der Suite-JSON über config.preparationMode gesetzt:
- Ich lade selbst (
userPreloaded, empfohlen) — Der Runner erwartet, dass Sie die PLCSIM-Instanz bereits manuell via TIA Portal gestartet und das Projekt geladen haben. Compile und Download werden übersprungen, der Runner verbindet sich direkt und führt die Tests aus. Schnellste Option für wiederholte Läufe am selben Projekt. - Automatischer TCP-Download (
tiaTcpDownload) — Der Runner kompiliert das Projekt, startet eine frische PLCSIM-Instanz und lädt es via TCP über den PLCSIM Virtual Adapter. Keine manuelle TIA-Portal-Interaktion nötig — einfach ausführen. - Reale PLC (kein PLCSim) (
external) — Überspringt den PLCSim-Lebenszyklus komplett. Der Runner verbindet sich via S7 Nativ direkt mit der echten S7-Hardware unter der konfigurierten IP und dem TCP-Port und führt die Tests dort aus. Nur verwenden, wenn die Anlage in einem sicheren Testzustand ist. Dieser Modus erfordert den Transport S7 Nativ; PLCSim API ist inkompatibel.
Vor der Verwendung von Automatischem TCP-Download: Vier Voraussetzungen müssen erfüllt sein, sonst schlägt der Run mit einem generischen Transport-Fehler fehl: (1) der PLCSIM Virtual Adapter muss installiert sein und eine statische IPv4-Adresse haben, die zur plcSimIp der Suite passt; (2) das TIA-Portal-Projekt muss in TIA Portal geöffnet sein — der Runner stösst vor dem Download eine Compile-Aktion gegen das offene Projekt an; (3) bei aktiviertem Vertraulichen Konfig-Schutz muss das Master-Secret-Passwort bereitgestellt werden (liegt im Vault); (4) eine bestehende PLCSIM-Instanz mit demselben Namen wird bei jedem Run zerstört und neu angelegt, sodass andere Anwendungen, die mit dieser Instanz verbunden sind, ihre Session verlieren.
Tests gegen reale PLC ausführen
Mit preparationMode auf Reale PLC (external) laufen Tests direkt gegen echte S7-1200/S7-1500-Hardware ohne PLCSim:
- Stellen Sie sicher, dass die Anlage im sicheren Testzustand ist — Aktoren freigeschaltet oder verriegelt, keine Produktionslast auf der PLC, Bediener informiert.
- Wählen Sie im
configder Suite S7 Nativ (s7CommPlus) als Transport, setzen Sie die echte IP-Adresse und (falls die SPS auf einen abweichenden TCP-Port konfiguriert wurde) den Port; Benutzer/Passwort nur falls die SPS Authentifizierung erzwingt. - Setzen Sie den Vorbereitungsmodus auf Reale PLC (kein PLCSim) (
external). - Führen Sie die Suite aus der Test-Suites-Ansicht aus.
- Bevor der Runner die PLC kontaktiert, erscheint ein Bestätigungsdialog: „Tests gegen reale PLC ausführen?" Lesen Sie die Warnung, setzen Sie den Haken bei „Verstanden — die Anlage ist im sicheren Testzustand.", dann klicken Sie Tests starten. Der Button bleibt deaktiviert, bis die Checkbox gesetzt ist. Mit Abbrechen wird der Lauf ohne Netzwerk-Verkehr verworfen.
F-Bausteine (mit Safety-Attribut markiert) bleiben in diesem Modus weiterhin hart geblockt — der Runner verweigert den Start jedes Tests gegen einen Safety-Block, unabhängig vom Vorbereitungsmodus.
Bricht der Lauf sofort mit „S7 connection succeeded but access denied — verify username/password" ab, hat die PLC den TLS-Handshake akzeptiert, aber die Credentials abgelehnt. Prüfen Sie Benutzer/Passwort im config der Suite und den passenden Eintrag unter Vault → S7-Passwort. Der Runner meldet das direkt beim Connect, damit der Test nicht später mit irreführendem „tag not found" scheitert.
Batch-Läufe und Reale-PLC-Suiten: Wenn Sie Run All Test Suites verwenden oder anders einen Batch-Lauf starten, der eine oder mehrere Suiten im Modus Reale PLC enthält, werden diese Suiten übersprungen (der Pro-Suite-Bestätigungsdialog kann nicht aus einem Batch heraus angezeigt werden). Die Test-Suites-Ansicht zeigt einen schliessbaren Banner, der die übersprungenen Suiten namentlich aufführt; öffnen Sie jede betroffene Suite und führen Sie sie einzeln aus, um den Bestätigungsdialog zu durchlaufen. Übersprungene Suiten zählen nicht mehr als Fehler in der Batch-Zusammenfassung.
CPU-Betriebszustands-Gate: Reale-PLC-Läufe lesen direkt nach Connect den Betriebszustand der CPU. Ist die CPU in Stop, StartUp, Hold, Defect oder einem anderen Nicht-RUN-Zustand, bricht der Runner sofort mit Cannot run tests against real PLC: CPU is in <STATE>, not Run. Switch the CPU to Run before retrying. ab. Damit schreibt der Runner nicht in den DB-Speicher, solange das Anwenderprogramm nicht läuft — sonst würde jeder Test residuale Daten zurücklesen und irreführende PASS/FAIL-Ergebnisse liefern. Schalten Sie die CPU auf RUN (TIA Portal Online & Diagnose, oder den Betriebsart-Wahlschalter an der CPU) und führen Sie erneut aus.
Test-Läufe gegen geschützte Projekte
Wenn Ihr TIA-Projekt „Schutz vertraulicher PLC-Konfigurationsdaten" aktiviert hat, erfordert der Automatischer-TCP-Download-Modus das Master-Secret-Passwort des Projekts:
- Den Vorbereitungsmodus im
configder Suite auf Automatischer TCP-Download (tiaTcpDownload) setzen - Das Master-Secret-Passwort des Projekts eingeben, wenn danach gefragt wird
- Optional: Passwort merken wählen, um es im Windows Credential Manager zu speichern — dann holt sich der Runner das Passwort bei jedem Folge-Lauf automatisch, ohne erneut nachzufragen. Sonst wird das Passwort einmal verwendet und nach dem Lauf vergessen
- Die Suite aus der Test-Suites-Ansicht ausführen
Beim nächsten Mal erscheint der Hinweis „Für diesen Benutzer ist ein Passwort gespeichert", wenn Sie es gespeichert haben. Lassen Sie das Passwortfeld leer, um das gespeicherte Passwort zu behalten. Passwort merken entfernen löscht den gespeicherten Eintrag.
Das Passwort wird nie in die Suite-Datei, in Logs oder Einstellungs-Dateien geschrieben. Es lebt ausschliesslich im Windows Credential Manager unter dem Servicenamen com.anyautomationstudio und wird vom Dialog zum Runner über einen benutzergebundenen DPAPI-Kanal übertragen, sodass ein anderer Windows-Benutzer es nicht lesen kann.
Suites und Testfälle verwalten
- Eine Suite umbenennen, indem Sie das JSON-
name-Feld oben in der Suite ändern und Save drücken — die Datei wird auf der Disk passend umbenannt (siehe Suite über das JSON-name-Feld umbenennen). Zum Löschen einer Suite die zugehörige.json-Datei aus dem.tia-tests/-Ordner entfernen. - Einen Testfall bearbeiten im Visual-Modus des Test-Suite-Editors: Jede Case-Zeile erlaubt Umbenennen, Beschreibung ändern, Duplicate, Entfernen sowie das Umsortieren der mehrstufigen Schritte über Move Up / Move Down.
- Den generierten SCL-Testcode bearbeiten in der SCL-Ansicht des Test-Suite-Editors: Testfälle umbenennen, Eingangswerte ändern, Assertions bearbeiten, ergänzen oder entfernen sowie ganze Testfall-Blöcke hinzufügen oder löschen. Änderungen fliessen automatisch in die Testfälle zurück, die Visual- und JSON-Ansicht zeigen sie sofort. Angaben, die im SCL-Text nicht vorkommen (Beschreibung, Zyklen, mehrstufige Schritte, Toleranz, Watch-Liste, Tags, Priorität, Verantwortlicher, Anforderungen), bleiben erhalten. Der Runner-Baustein am Ende wird automatisch nachgeführt, Änderungen daran haben keine Wirkung. Passt der Text nicht mehr zur Struktur der Testbausteine, erscheint eine Fehlermeldung mit Zeilennummer; Save und Import to TIA bleiben blockiert, bis sie behoben ist. Beim Wechsel zu einem anderen Editor-Tab wird noch nicht übernommener SCL-Text verworfen, bereits übernommene Änderungen bleiben erhalten.
- Verbindungseinstellungen gelten pro Suite. Transport, PLCSim-Instanzname, IP-Adresse, Zyklus-Wartezeit, S7-Comm+-Ziel (IP, TCP-Port, Benutzer, Passwort) und Auto-Connect liegen alle im
config-Block der Suite-Datei. Sie werden mit der Suite gespeichert, sodass beim nächsten Öffnen dieselben Werte wirken. Passwörter bleiben weiterhin im Windows Credential Manager — die Suite-Datei speichert nur eine Referenz, nie ein Klartext-Passwort. (Ein Verbindungseinstellungen…-Formular, um diese ohne JSON-Bearbeitung zu setzen, ist geplant — siehe Transport auswählen.) - Vor jedem Lauf prüft Studio, dass jeder Variablenname in Ihrer Suite exakt dem Baustein-Interface entspricht — inklusive Gross-/Kleinschreibung. Werden Abweichungen gefunden, zeigt ein Warndialog die Korrekturvorschläge an; Sie können den Lauf nach Bestätigung trotzdem starten.
- Schlägt ein Testfall fehl, erscheint seine Fehlermeldung unter dem Case-Namen in der Test-Results-Ansicht (und beim Hovern), und das Detail-Grid markiert die fehlgeschlagene Assertion mit einem roten ✗ neben Erwartet- und Tatsächlich-Wert. (Der Sprung von einem fehlgeschlagenen Case direkt zu der Variable im Test-Suite-Editor ist geplant.)
- Wird eine Suite-Datei extern geändert — oder über das JSON-
name-Feld oben umbenannt — lädt der offene Editor sie automatisch neu. Sind jedoch noch ungespeicherte Änderungen vorhanden, bleiben diese erhalten.
Fehlerbehebung
- Status-Icons aktualisieren sich nicht nach einem Lauf: Prüfen ob der Suite-Dateipfad korrekt ist (absoluter Pfad unter
.tia-tests/). Neue ungespeicherte Suites bekommen pro Klick einen eindeutigen Pfad. - Run-Aktion nicht verfügbar: Ein TIA-Projekt muss geöffnet sein, und das aktive Suite-Dokument muss valides JSON sein.
- Test Explorer ist leer: Das Arbeitsverzeichnis hat noch keinen
.tia-tests/Ordner. New Test Suite klicken um die erste Suite zu erstellen — der Ordner wird automatisch angelegt. - PLCSIM-Fehler: Prüfen ob PLCSIM Advanced V3.0+ installiert und lizenziert ist. Die genaue Version wird zur Laufzeit automatisch erkannt.
- TLS-Verkehr für den Support aufzeichnen (fortgeschritten): Wenn der Support einen Wireshark-Mitschnitt des S7-Comm+-Handshakes braucht, die Umgebungsvariable
SSLKEYLOGFILEvor dem Start der App auf einen absoluten Dateipfad setzen — z.B.setx SSLKEYLOGFILE "C:\Temp\s7-keys.log"— und anschliessend neu starten. In Wireshark die TLS-Einstellung (Pre)-Master-Secret log filename auf dieselbe Datei zeigen lassen. Solange die Variable gesetzt ist, wird bei jeder Verbindung eine Warnung ins App-Log geschrieben, damit sie nicht vergessen wird. Im Normalbetrieb die Variable leer lassen.
KI-geschriebene Test-Suites (Enterprise)
Der AI-Chat kann komplette SCL-Unit-Test-Suites für Sie entwerfen, verfeinern und (optional) ausführen. Benötigt eine Enterprise-Lizenz.
Skill „Write Unit Tests" (Hauptchat)
- AI Chat öffnen und im Skill-Picker den Skill Write Unit Tests auswählen (🧪-Icon) — oder einfach fragen: „schreib Unit-Tests für FB_MotorControl"
- Der Assistent liest das Baustein-Interface, berechnet Grenzwerte, plant Testfälle und fasst den Plan im Chat zusammen — ohne riesige JSON-Blöcke
- Wenn er die Suite schreiben möchte, erscheint inline ein Erlauben- / Ablehnen-Prompt. Erlauben speichert die Suite nach
.tia-tests/ - Wenn Sie den Assistenten gebeten haben, die Suite auch auszuführen, erscheint ein zweiter Approval-Prompt für den Run selbst. Die Ergebnisse kommen als Pass/Fail-Zusammenfassung zurück in den Chat, und der Assistent bietet an, fehlgeschlagene Testfälle nachzubessern
- Die Test-Suites-Ansicht übernimmt die neue Suite automatisch — öffnen, im Visual-Modus oder als JSON-Text prüfen und nach Wunsch selbst laufen lassen
- Nach dem Anlegen können Sie auch direkt „öffne die Suite" schreiben — die Suite wird im Test-Suite-Editor geöffnet, ohne dass Sie zur Test-Suites-Ansicht wechseln müssen
Inline-Chat im Suite-Editor (Strg+I)
Während eine Test-Suite im JSON-Editor geöffnet ist:
- Den Cursor nahe des zu ändernden Testfalls platzieren (oder einen Bereich markieren)
Strg+Idrücken — oberhalb des Editors erscheint ein kleines Prompt-Feld- Eingeben, was geändert werden soll, zum Beispiel:
- „füg einen Overflow-Test für Counter_Value hinzu"
- „mach daraus einen parametrisierten Test mit fünf Sollwerten"
- „setz die Toleranz aller REAL-Assertions auf 0.01"
- Der Assistent streamt das aktualisierte JSON, und im Editor erscheint ein Diff-Overlay
- Akzeptieren übernimmt die Änderung (die Datei wird gespeichert und der Test Explorer lädt neu); Ablehnen verwirft sie
Der Inline-Chat nutzt dasselbe Baustein-Interface, mit dem die Suite geöffnet wurde, sodass Variablennamen und Typen gegen den echten Baustein geprüft werden — Abweichungen fallen vor dem Speichern auf.
KI-Badge im Test Explorer und Visual-Editor
Von der KI erstellte TestCases tragen ein kleines AI-Tag, das erscheint:
- neben dem Testfall-Namen im Visual-Editor
- im Test Explorer-Baum
Überprüfen Sie KI-geschriebene Testfälle wie einen Pull Request von einer Kollegin — jede Assertion lesen, erwartete Werte plausibilisieren, erst am Simulator laufen lassen und dann auf echter Hardware.
Safety-Schutz (F-CPU)
Das KI-gestützte Schreiben von Tests ist für Safety-Bausteine abgesichert:
- Tests erstellen — Der Assistent verweigert das Schreiben von Tests für einen F-CPU-Baustein ohne eine explizite Bestätigung im Gespräch. Auch die darunterliegenden Tools lehnen den Schreibvorgang ohne diese Bestätigung ab
- Tests ausführen — Der Assistent kann keine Tests gegen Safety-Bausteine laufen lassen. Punkt. Kein Override. Safety-Baustein-Verifikation erfordert eine zertifizierte Methodik (TÜV/CE), keinen KI-Run. Wenn Sie einen Test gegen einen Safety-Baustein laufen lassen wollen, starten Sie den Run selbst aus dem Test Explorer
Lizenzierung
Der Skill „Write Unit Tests" und die Unit-Test-MCP-Tools sind Enterprise-only. In den Tiers Basic oder Professional zeigt der Skill vor jedem KI-Call eine „Enterprise erforderlich"-Meldung.
CI/CD-Integration
Das Kommandozeilen-Werkzeug tia-test-runner führt Ihre SCL-Unit-Test-Suiten auf einem Build-Server aus — ohne Oberfläche, ohne manuelle Klicks. Sie zeigen darauf auf ein TIA-Portal-Projekt; das Werkzeug findet die Suiten in .tia-tests/, führt sie aus, schreibt maschinenlesbare Berichte und liefert einen Exit-Code zurück, auf den Ihre Pipeline reagieren kann. Es handelt sich um eine Enterprise-Funktion; es gelten dieselben Lizenzregeln wie für den Arbeitsbereich in der App (siehe Lizenzierung für CI weiter unten).
Das Kommandozeilen-Werkzeug tia-test-runner
Das Werkzeug wird als tia-test-runner.exe ausgeliefert und stellt sechs Verben bereit:
| Verb | Zweck |
|---|---|
run | Einen Unit-Test-Lauf gegen ein TIA-Portal-Projekt ausführen und Berichte schreiben |
compare | Zwei frühere Läufe vergleichen und einen Diff-Bericht erzeugen |
trend | Historische Pass/Fail-Trends als CSV exportieren |
validate | Test-Suite-Definitionen auf Schema-Fehler prüfen, ohne sie auszuführen |
verify | Das Integritäts-Manifest eines früheren Laufs prüfen (manipulierte oder fehlende Bericht-Dateien erkennen) |
version | Versionen von Runner, Bridge, Engine, Build, .NET und Betriebssystem ausgeben |
Ein typischer Lauf:
tia-test-runner run ^
--project "C:\Projects\Plant.ap20" ^
--plc PLC_1 ^
--suite-filter * ^
--out-dir reports
Wichtige Flags für run:
| Flag | Bedeutung |
|---|---|
--project <PFAD> | TIA-Portal-Projektdatei (.ap20, .ap21, …). Erforderlich. |
--out-dir <PFAD> | Verzeichnis für Berichte und Logs. Erforderlich. |
--plc <NAME> | Den Lauf auf eine einzelne PLC-Station begrenzen. |
--suite-filter <MUSTER> | Glob-Filter auf Suite-Namen (*, ?, literal). |
--tag <TAG> | Nur Fälle mit diesem Tag ausführen (wiederholbar). |
--priority-min <STUFE> | Mindestpriorität (Low / Normal / High / Critical). |
--report-format <FORMAT> | junit, html oder json (wiederholbar). Standard: JUnit + HTML. |
--rerun-affected | Nur Suiten ausführen, deren zugrunde liegender Baustein sich seit dem letzten Lauf geändert hat (benötigt --plc). |
--fail-fast | Beim ersten fehlgeschlagenen Fall abbrechen. |
--timeout-minutes <N> | Zeitlimit pro Lauf. Standard: 60. |
--attach | An ein bereits laufendes TIA Portal anhängen, statt die Projektdatei zu öffnen. |
--config <PFAD> | Standardwerte aus einer YAML-Konfigurationsdatei lesen (siehe unten). |
Exit-Codes (der Pipeline-Vertrag):
| Code | Bedeutung |
|---|---|
0 | Alle Tests bestanden |
1 | Ein oder mehrere Tests fehlgeschlagen |
2 | Lauffehler (Start nicht möglich, PLC-Verbindung verloren, Lizenz nicht berechtigt, …) |
3 | Argument- oder Konfigurationsfehler |
4 | Zeitüberschreitung |
5 | Vom Benutzer abgebrochen (Strg+C) |
Nach einem Lauf enthält --out-dir eine JUnit-XML-Datei, die Ihr CI-Test-Reporter veröffentlichen kann, einen eigenständigen, gebrandeten HTML-Bericht und ein Integritäts-Manifest. Berichte sind append-only: Ein zweiter Lauf in dasselbe Verzeichnis behält den früheren Lauf und ergänzt eine aggregierte Zusammenfassung.
Bericht-Klassennamen
Standardmäßig folgen die JUnit-classname-Werte dem Muster {PlcName}.{BlockName}, das die meisten CI-Test-Ansichten zu einem lesbaren Baum gruppieren. Überschreiben Sie es mit --report-classname-pattern und einer beliebigen Kombination dieser Platzhalter:
{PlcName}— der PLC-/CPU-Name{BlockName}— der getestete Baustein{SuiteName}— der Name der Test-Suite{ProjectName}— der Projektname
Beispiel: --report-classname-pattern "{ProjectName}/{PlcName}/{SuiteName}".
CI-Umgebungsdaten erfassen
Mit --ci-env-capture wird eine kleine, feste Auswahl von CI-Variablen in die Herkunftsdaten des Laufs aufgenommen, damit die Berichte zeigen, welche Pipeline, welcher Commit und welcher Agent den Lauf erzeugt hat. Die Erfassung ist opt-in — ohne ausdrückliche Angabe wird nichts erfasst. Das Werkzeug erkennt GitHub Actions, Jenkins, Azure DevOps und GitLab CI (sowie einen generischen CI-Marker); gelesen wird nur eine erlaubte Auswahl an Bezeichnern (Lauf-/Build-IDs, Commit-SHA, Branch/Ref, Workflow-/Job-Name, Agent-/Runner-Name), jeweils auf eine sichere Länge gekürzt.
YAML-Konfigurationsdatei
Damit lange Befehlszeilen aus Ihrer Pipeline verschwinden, legen Sie die Standardwerte in einer YAML-Datei ab und übergeben --config <PFAD>. Befehlszeilen-Flags überschreiben die Datei. Beispiel tia-tests.yml:
project: C:\Projects\Plant.ap20
plc: PLC_1
out_dir: reports
report_format:
- junit
- html
timeout_minutes: 45
ci_env_capture: true
Jenkins (Declarative Pipeline)
pipeline {
agent { label 'tia-windows' }
stages {
stage('Checkout') {
steps { checkout scm }
}
stage('Unit Tests') {
steps {
bat 'tia-test-runner run --project "%WORKSPACE%\\Plant.ap20" --plc PLC_1 --out-dir reports --ci-env-capture'
}
}
}
post {
always {
junit 'reports/**/junit.xml'
archiveArtifacts artifacts: 'reports/**/*.html', allowEmptyArchive: true
}
}
}
GitHub Actions
name: TIA Unit Tests
on: [push]
jobs:
unit-tests:
runs-on: [self-hosted, windows, tia]
steps:
- uses: actions/checkout@v4
- name: Run SCL unit tests
run: tia-test-runner run --project "${{ github.workspace }}\Plant.ap20" --plc PLC_1 --out-dir reports --ci-env-capture
- name: Publish test report
if: always()
uses: dorny/test-reporter@v1
with:
name: TIA Unit Tests
path: reports/**/junit.xml
reporter: java-junit
- name: Upload HTML report
if: always()
uses: actions/upload-artifact@v4
with:
name: tia-html-report
path: reports/**/*.html
Azure DevOps
pool:
name: tia-windows
steps:
- checkout: self
- script: tia-test-runner run --project "$(Build.SourcesDirectory)\Plant.ap20" --plc PLC_1 --out-dir $(Build.ArtifactStagingDirectory)\reports --ci-env-capture
displayName: Run SCL unit tests
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: JUnit
testResultsFiles: '$(Build.ArtifactStagingDirectory)/reports/**/junit.xml'
testRunTitle: TIA Unit Tests
- publish: $(Build.ArtifactStagingDirectory)\reports
artifact: tia-html-report
condition: always()
GitLab CI
unit-tests:
tags: [tia-windows]
script:
- tia-test-runner run --project "$CI_PROJECT_DIR\Plant.ap20" --plc PLC_1 --out-dir reports --ci-env-capture
artifacts:
when: always
paths:
- reports/
reports:
junit: reports/**/junit.xml
Eine CI/CD-Pipeline aus der App erzeugen
Geplant für den In-App-Arbeitsbereich. Ein In-App-Generator für diese Dateien ist geplant. Bis dahin kopieren Sie eine der obigen Vorlagen. Der vorgesehene Ablauf:
Statt die Konfigurationsdateien von Hand zu schreiben, würden Sie sie von AnyAutomation Studio erzeugen lassen. Der Generator liest das geöffnete Projekt und erstellt zwei direkt eincheckbare Dateien: eine runner.yaml mit den Kommandozeilen-Vorgaben und eine Pipeline-Datei für das von Ihnen gewählte CI-System.
Der vorgesehene Ablauf:
- Öffnen Sie ein Projekt.
- Öffnen Sie die Test-Suites-Ansicht.
- Starten Sie Pipeline erzeugen….
- Wählen Sie Ihr CI-System (GitHub Actions, Jenkins, Azure DevOps oder GitLab CI) und passen Sie die vorausgefüllten Felder an — Projektpfad, PLC-Name, einen optionalen Suite-Filter, den Berichtsausgabeordner, die zu schreibenden Berichtsformate, eine optionale Bezeichnung des selbstgehosteten Runners und ein optionales Bericht-Branding.
- Vorschau erzeugen, um beide Dateien nebeneinander zu sehen.
- Dateien schreiben, um sie zu speichern. Falls eine Datei bereits existiert, werden Sie vor dem Überschreiben gefragt.
Die runner.yaml wird in den Projektordner geschrieben, die Pipeline-Datei an den vom CI-System erwarteten Pfad: .github/workflows/tia-tests.yml für GitHub Actions, Jenkinsfile für Jenkins, azure-pipelines.yml für Azure DevOps und .gitlab-ci.yml für GitLab CI. Checken Sie beide Dateien ein. Die erzeugte Pipeline läuft auf Abruf — starten Sie sie manuell in Ihrem CI-System, wann immer Sie testen möchten, statt automatisch bei jedem Push.
Die Pipeline muss auf einem selbstgehosteten Windows-Runner laufen. Die Tests steuern TIA Portal und PLCSIM, daher benötigt die ausführende Maschine ein installiertes TIA Portal, ein verfügbares PLCSIM und eine aktive Enterprise-Lizenz. Cloud-gehostete Runner können die Tests nicht ausführen. Tragen Sie die Bezeichnung Ihres eigenen Windows-Runners im Feld Bezeichnung des selbstgehosteten Runners ein, damit die erzeugte Pipeline ihn anspricht; lassen Sie das Feld nur dann leer, wenn Sie einen selbstgehosteten Runner bereits auf anderem Weg eingerichtet haben.
Lizenzierung für CI
Unit Testing ist eine Enterprise-Funktion, daher prüft der Runner die Lizenz, bevor er arbeitet. Es gibt drei Möglichkeiten, einen CI-Agenten zu lizenzieren:
- Maschinengebunden (Standard) — der Agent nutzt die auf dieser Maschine bereits aktivierte Lizenz, genau wie die Desktop-App. Am besten für einen dedizierten, langlebigen Build-Server.
- Schlüssel pro Lauf — übergeben Sie
--license-key <SCHLÜSSEL>, um zu Beginn des Laufs zu aktivieren. Der Schlüssel wird in allen Logs maskiert. - Offline (lokal zwischengespeichert) — übergeben Sie
--license-offline <PFAD>auf Agenten mit eingeschränktem Netzzugang. Der Runner versucht keine Online-Aktivierung, sondern stützt sich auf die lokal zwischengespeicherte, signierte Lizenz.
Offline-Einschränkung — bitte lesen. Der Offline-Modus ist eine zwischengespeicherte, kulanzbasierte Lizenz, keine vollständig abgeschottete (air-gapped) Aktivierung. Sie funktioniert rund 14 Tage nach der letzten erfolgreichen Online-Prüfung. Ein Agent, der das Netz nie wieder erreicht, verliert seine Berechtigung, sobald dieses Kulanzfenster abläuft; der Lauf schlägt dann mit Exit-Code
2fehl. Damit ein Offline-Agent grün bleibt, lassen Sie ihn regelmäßig online prüfen (zum Beispiel über einen geplanten Job). Ein eigener Import einer Offline-Aktivierungsdatei ist für eine spätere Version geplant; bis dahin wird der an--license-offlineübergebene Pfad im Log vermerkt und die zwischengespeicherte/kulanzbasierte Lizenz verwendet.
Proxy-Konfiguration
Der Runner berücksichtigt standardmäßig die üblichen Proxy-Umgebungsvariablen — setzen Sie HTTPS_PROXY, HTTP_PROXY und NO_PROXY auf dem Build-Agenten, dann läuft die Online-Lizenzprüfung über Ihren Proxy. Zusätzliche Flags sind nicht nötig.
Unterstützte Umgebungen
| Umgebung | Unterstützt? | Hinweise |
|---|---|---|
| Windows 11 (Desktop) | Ja | Referenzumgebung. |
| Windows Server 2022 mit Desktopdarstellung | Ja | TIA Portal und PLCSIM Advanced benötigen eine interaktive Desktop-Sitzung. |
| Windows Server Core | Nein | TIA Portal Openness benötigt die vollständige Desktop-Shell, die die Server-Core-Installation nicht bereitstellt. |
| Docker / Windows-Container | Nein | TIA Portal und PLCSIM Advanced werden in Containern nicht unterstützt. |
Fehlerbehebung bei CI-Läufen
| Symptom | Ursache und Behebung |
|---|---|
Exit-Code 3, „--project is required" | Ein erforderliches Argument fehlt oder die YAML-Konfiguration konnte nicht gelesen werden. Prüfen Sie die Pfade von --project, --out-dir und --config. |
Exit-Code 2, Lizenzmeldung | Der Agent hat keine gültige Berechtigung. Aktivieren Sie eine maschinengebundene Lizenz, übergeben Sie --license-key oder — bei Offline-Agenten — stellen Sie sicher, dass die zwischengespeicherte Lizenz innerhalb der letzten ~14 Tage online geprüft wurde. |
Exit-Code 2, „Ausgabeverzeichnis kann nicht beschrieben werden" | --out-dir zeigt auf einen geschützten Systemort. Verwenden Sie einen Pfad unterhalb des Projektverzeichnisses oder im lokalen App-Daten-Bereich des Agenten. |
Exit-Code 4, Zeitüberschreitung | Der Lauf überschritt --timeout-minutes. Erhöhen Sie das Limit oder teilen Sie große Suiten auf; prüfen Sie, ob die PLC vom Agenten erreichbar ist. |
| Kein Testbericht in CI sichtbar | Der Test-Reporter-Schritt zeigt nicht auf junit.xml oder läuft nur bei Erfolg. Veröffentlichen Sie Berichte mit einer always()/when: always-Bedingung und zeigen Sie auf reports/**/junit.xml. |
| Online-Prüfung hängt hinter einem Unternehmens-Proxy | Setzen Sie HTTPS_PROXY / HTTP_PROXY (und NO_PROXY für interne Hosts) auf dem Agenten. |
Datenschutz
Es werden keine Telemetriedaten durch die CLI oder die Oberfläche erhoben. Die in Berichten sichtbaren CI-Variablen werden nur erfasst, wenn Sie dies mit --ci-env-capture ausdrücklich aktivieren, und der Projektpfad wird als nicht umkehrbarer Hash gespeichert, niemals im Klartext. HTML-Berichte erfüllen WCAG 2.1 AA, geprüft durch automatisierte Checks; eine manuelle Screenreader-Abnahme (NVDA) ist Teil des Release-End-to-End-Durchlaufs.