Robot-Framework-Tests fachlich beurteilen mit KI
von Rainer Haupt
TL;DR: RF-Keywords sind natürliche Sprache — Sentence-Embeddings (SBERT) erkennen fachliche Redundanz mit F-Score 87 % (Viggiato et al., IEEE TSE 2023). LLM-as-a-Judge bewertet Testabdeckung gegen Jira-Akzeptanzkriterien: GPT-4o Mini erreicht 6.07 MAAE bei rund USD 1.01 pro 1’000 Bewertungen. RF-Tags und Keyword-Namen bilden eine semantische Brücke zwischen Requirements und Tests, ohne Code-Verständnis. Die grösste offene Lücke: Stand 2026 kombiniert kein Tool RF-Testsuite + Jira-Stories + LLM zu einer automatischen Gap-Analyse — eine unbesetzte Nische. Gegenargument: Die RF-Keyword-Abstraktion verbirgt Implementierungsdetails, die ein LLM für bestimmte Bewertungen bräuchte.
Lesedauer ca. 18 Min · Stand: 2026-04
Fachliche Redundanzerkennung — warum RF-Syntax für LLMs transparenter ist
In gewachsenen Testsuites mit 500+ Tests entstehen fachliche Redundanzen nicht durch Copy-Paste, sondern durch semantische Überlappung: Zwei Tests prüfen dasselbe Geschäftsszenario, geschrieben von verschiedenen Personen zu verschiedenen Zeiten. Die Testnamen unterscheiden sich, die Implementierung unterscheidet sich — fachlich testen aber beide dasselbe.
Warum RF strukturell im Vorteil ist
Ein LLM oder Embedding-Modell muss bei der Redundanzsuche die fachliche Intention eines Tests erkennen. Bei RF liegt diese Intention offen.
RF-Testpaar — fachlich redundant:
*** Test Cases ***
Verify User Can Login With Valid Credentials
Open Browser To Login Page
Input Username demo
Input Password mode
Submit Credentials
Welcome Page Should Be Open
Verify Successful Authentication With Correct Data
Navigate To Login
Enter Username demo
Enter Password mode
Click Login
Dashboard Should Be Visible
Ein Sentence-Embedding-Modell (SBERT) berechnet für die Testnamen eine hohe Cosine-Similarity (rund 0.85+), weil beide aus geläufigen englischen Wörtern bestehen. Auch die Keyword-Sequenzen sind semantisch nah: «Open Browser To Login Page» liegt nah bei «Navigate To Login», «Submit Credentials» bei «Click Login».
Dasselbe Testpaar in pytest:
def test_login_valid(self, driver):
driver.get("http://localhost:7272")
driver.find_element(By.ID, "username_field").send_keys("demo")
driver.find_element(By.ID, "password_field").send_keys("mode")
driver.find_element(By.ID, "login_button").click()
assert driver.current_url.endswith("/welcome.html")
def test_auth_success(self, browser):
browser.navigate().to("http://localhost:7272")
browser.find_element(By.CSS_SELECTOR, "#username").send_keys("demo")
browser.find_element(By.CSS_SELECTOR, "#password").send_keys("mode")
browser.find_element(By.CSS_SELECTOR, "button[type=submit]").click()
WebDriverWait(browser, 10).until(EC.title_is("Dashboard"))
Hier muss das LLM verstehen, dass By.ID, "username_field" und By.CSS_SELECTOR, "#username" auf dasselbe Element zeigen, dass .click() auf login_button versus button[type=submit] funktional identisch ist und dass assert driver.current_url.endswith("/welcome.html") dasselbe prüft wie EC.title_is("Dashboard"). Das ist technische Analyse, nicht fachliche — und genau die ist für Embedding-Modelle schwierig, weil die Tokens keinen natürlichsprachlichen Kontext haben.
Was die Forschung sagt
Die Viggiato-Studie (IEEE TSE 2023) ist die zentrale Referenz: F-Score 87.39 % bei der Clusterung ähnlicher Testschritte und 83.47–86.13 % bei Testfällen — unter Verwendung von SBERT + Cosine Similarity + hierarchischem Clustering. Die Studie wurde auf natürlichsprachlichen Testfällen durchgeführt, was exakt dem RF-Format entspricht.
Für Code-basierte Tests empfiehlt die LTM-Studie (Pan et al., IEEE TSE 2024) spezialisierte Code-Embedding-Modelle wie UniXcoder — die zwar funktionieren, aber eine höhere Einstiegshürde haben und die fachliche Ebene schlechter abbilden.
Der entscheidende Punkt: RF-Tests fallen direkt in die Kategorie «natürlichsprachliche Testfälle», für die SBERT-Embeddings optimiert sind. pytest-Tests fallen in die Kategorie «Code», die spezialisierte Code-Embeddings erfordert. Bei fachlicher Redundanzsuche will man aber gerade die natürlichsprachliche Ebene — und da ist RF im Sweet Spot.
Testabdeckung gegen Requirements — Jira-Stories, Akzeptanzkriterien, Wikis
Ein Team hat 200 RF-Tests und 50 Jira-Stories mit Akzeptanzkriterien. Die Frage: Welche Akzeptanzkriterien sind durch Tests abgedeckt? Welche nicht? Wo gibt es Lücken?
Warum RF das LLM-Matching erleichtert
Jira Story:
Als Benutzer möchte ich mein Passwort zurücksetzen können,
damit ich wieder Zugang zu meinem Konto erhalte.
Akzeptanzkriterien:
- AC1: Benutzer kann Reset über E-Mail-Link anfordern
- AC2: Link läuft nach 24 Stunden ab
- AC3: Neues Passwort muss mind. 8 Zeichen haben
- AC4: Altes Passwort wird nach Reset ungültig
- AC5: Benutzer erhält Bestätigungs-E-Mail nach Änderung
RF-Testsuite:
*** Test Cases ***
User Requests Password Reset Via Email [Tags] password-reset AC1
Navigate To Login Page
Click Forgot Password Link
Enter Email Address user@example.com
Submit Reset Request
Reset Email Should Be Received
Reset Link Expires After 24 Hours [Tags] password-reset AC2
Request Password Reset
Wait 24 Hours # simulated
Open Reset Link
Page Should Contain Link expired
New Password Must Meet Minimum Length [Tags] password-reset AC3
Open Valid Reset Link
Enter New Password short
Submit New Password
Error Message Should Be Visible Minimum 8 characters
Ein LLM kann hier direkt matchen: AC1 ↔ «User Requests Password Reset Via Email», AC2 ↔ «Reset Link Expires After 24 Hours», AC3 ↔ «New Password Must Meet Minimum Length». Die Tags (AC1, AC2, AC3) sind ein zusätzliches Signal, aber selbst ohne Tags wäre das semantische Matching über die Testnamen hochgenau.
Was fehlt? AC4 und AC5 haben keinen passenden Test — Gap identifiziert.
Dasselbe in pytest:
def test_password_reset_request(self, driver): ...
def test_reset_link_expiry(self, driver): ...
def test_password_min_length(self, driver): ...
Die abgekürzten Funktionsnamen (test_password_reset_request) tragen weniger semantisches Signal als die RF-Testnamen. Ohne Docstrings oder Kommentare muss das LLM den Code lesen, um die fachliche Intention zu verstehen. Möglich, aber fehleranfälliger und aufwändiger.
LLM-as-a-Judge — gewichtete Rubrik für Testabdeckung
Das LAJ-Framework (LLM-as-a-Judge) verwendet eine vierdimensionale gewichtete Rubrik: Szenario-Vollständigkeit (40 %), Akzeptanzkriterien-Alignment (30 %), HTTP-methodenspezifische Aspekte (20 %) und Assertion-Qualität (10 %).
In der Studie wurde eine dreistufige Pipeline getestet:
- Jira-Ticket mit Akzeptanzkriterien — von Product Ownern erstellt
- Gherkin-Tests — generiert oder manuell geschrieben
- LLM-Bewertung — GPT-4o Mini bewertet Abdeckung gegen Kriterien
Ergebnis: GPT-4o Mini erreicht die beste Genauigkeit (6.07 MAAE) bei hoher Zuverlässigkeit (96.6 % ECR@1) und niedrigen Kosten (rund USD 1.01 pro 1’000 Bewertungen) — eine 78-fache Kostenreduktion gegenüber GPT-5.
RF-Relevanz: Die Studie nutzt Gherkin (Given-When-Then), das RF nativ unterstützt. RF-Tests mit BDD-Syntax (Given ... When ... Then ...) fallen direkt in dieses Schema. Aber auch ohne BDD-Syntax sind RF-Keyword-Namen semantisch nah genug für das Matching.
Multi-Source-Analyse — Jira + Wiki + PDF + Tests
Das reale Szenario ist komplexer: Requirements verteilt über Jira-Stories, Confluence-Wikis, PDF-Spezifikationen und E-Mail-Threads. Ein RAG-basierter Ansatz (Retrieval-Augmented Generation) kann alle Quellen in einen Vektor-Index laden und RF-Tests dagegen matchen.
Pipeline-Skizze:
- Jira-API → Stories und Akzeptanzkriterien extrahieren
- Confluence-API → Wiki-Seiten mit Fachspezifikationen
- PDFs → Text extrahieren
- Alles in Vektor-DB (z. B. Chroma, Pinecone) embedden
- RF-Tests parsen → Testname + Keywords + Tags +
[Documentation]als Text - Für jeden Test: Nearest-Neighbor-Suche in der Requirements-DB
- Für jedes Requirement: Prüfen, ob ein Test mit hoher Similarity existiert
- Gaps = Requirements ohne nahen Test-Match
RF-Tests erzeugen in Schritt 5 deutlich bessere Text-Repräsentationen als pytest, weil Testname und Keyword-Sequenz bereits natürliche Sprache sind. Bei pytest müsste man den Code erst in eine natürlichsprachliche Beschreibung übersetzen (z. B. via LLM-Zusammenfassung), was einen zusätzlichen fehleranfälligen Schritt einführt.
Äquivalenzklassen und Grenzwertanalyse — kann ein LLM fehlende Tests finden
Ein Requirement sagt: «Das Alter des Benutzers muss zwischen 18 und 65 liegen.» Ein LLM soll prüfen, ob die Testsuite die richtigen Äquivalenzklassen und Grenzwerte abdeckt.
Die erwarteten Testfälle nach ISTQB:
| Äquivalenzklasse | Werte | Erwartet |
|---|---|---|
| Unter Minimum (ungültig) | 17, 0, -1 | Ablehnung |
| Minimum-Grenzwert (gültig) | 18 | Akzeptanz |
| Gültig (Mitte) | 30, 42 | Akzeptanz |
| Maximum-Grenzwert (gültig) | 65 | Akzeptanz |
| Über Maximum (ungültig) | 66, 100, 999 | Ablehnung |
RF macht die Datenwerte sichtbar — pytest versteckt sie
RF mit Test Template:
*** Settings ***
Test Template Age Validation Should
*** Test Cases *** AGE EXPECTED
Below Minimum 17 Reject
Minimum Boundary 18 Accept
Valid Middle 30 Accept
Maximum Boundary 65 Accept
Above Maximum 66 Reject
Zero 0 Reject
Negative -1 Reject
*** Keywords ***
Age Validation Should
[Arguments] ${age} ${expected}
Enter Age ${age}
Submit Form
Result Should Be ${expected}
pytest mit parametrize:
@pytest.mark.parametrize("age,expected", [
(17, "Reject"),
(18, "Accept"),
(30, "Accept"),
(65, "Accept"),
(66, "Reject"),
(0, "Reject"),
(-1, "Reject"),
])
def test_age_validation(driver, age, expected):
driver.find_element(By.ID, "age").clear()
driver.find_element(By.ID, "age").send_keys(str(age))
driver.find_element(By.ID, "submit").click()
result = driver.find_element(By.ID, "result").text
assert result == expected
Auf den ersten Blick sieht die Abdeckung in beiden Fällen gleich aus. Aber drei Punkte machen den Unterschied für die LLM-Analyse.
Sprechende Testnamen. «Below Minimum», «Minimum Boundary», «Maximum Boundary» — das LLM erkennt sofort die Testdesign-Intention. Bei pytest heissen alle Varianten gleich: test_age_validation[17-Reject], test_age_validation[18-Accept]. Die fachliche Klassifikation fehlt.
Tabellarische Struktur. Die Daten sind als Tabelle formatiert — AGE und EXPECTED als Spalten. Ein LLM kann diese Tabelle direkt als Äquivalenzklassen-Matrix lesen. Bei pytest sind die Daten als Python-Tuple-Liste im Dekorator versteckt.
LLM-Prompt für Gap-Analyse. Mit der RF-Syntax kann das LLM auf einen Prompt wie folgt direkt antworten:
Hier ist ein Requirement: «Alter muss zwischen 18 und 65 liegen.»
Hier sind die aktuellen RF-Testfälle: [Testliste einfügen]
Prüfe:
1. Sind alle Äquivalenzklassen abgedeckt?
2. Sind die Grenzwerte 17, 18, 65, 66 getestet?
3. Welche Testfälle fehlen?
Das LLM versteht die Testnamen und Werte als natürliche Sprache. Eine aktuelle Studie zur LLM-generierten Grenzwertanalyse zeigt, dass 63.5 % aller Bewertungen positiv ausfielen (4–5 auf einer Fünf-Punkte-Likert-Skala), wobei Software-Professionals klare Struktur und praktische Beispiele besonders schätzten. Eine zweite Studie evaluiert LLMs bei der Generierung von Tests mit Äquivalenzklassen und Grenzwerten und zeigt, dass die Effektivität stark von präzisen Requirements und gut designten Prompts abhängt.
Was ein LLM in dieser Testsuite als fehlend erkennen könnte
Ein gutes LLM würde bei der Analyse Folgendes anmerken:
- Fehlende Äquivalenzklasse: nicht-numerische Eingaben (Buchstaben, Sonderzeichen, Leerstring)
- Fehlender Grenzwert: Dezimalzahlen (17.5, 18.0, 65.5)
- Fehlender Edge Case: sehr grosse Zahlen (9999999), führende Nullen («018»)
- Fehlende Negativ-Tests: SQL-Injection im Altersfeld, XSS
Bei RF erkennt das LLM diese Lücken leichter, weil die vorhandene Testabdeckung als fachliche Tabelle vorliegt. Bei pytest muss es erst die Tuple-Liste parsen und die fachliche Bedeutung der Werte rekonstruieren.
RF-Tags als Requirements-Traceability-Mechanismus
RF bietet mit Tags einen eingebauten Mechanismus, der für LLM-basierte Analyse ideal ist:
*** Test Cases ***
Admin Creates User [Tags] JIRA-1234 admin user-mgmt smoke
...
User Edits Own Profile [Tags] JIRA-1235 user profile regression
...
Admin Deletes User [Tags] JIRA-1236 admin user-mgmt critical
...
Was ein LLM mit Tags machen kann:
- Traceability-Matrix generieren — welcher Test gehört zu welcher Jira-Story
- Coverage-Report — für JIRA-1234 gibt es drei Tests, für JIRA-1237 keinen → Gap
- Risiko-Analyse — Tests mit Tag
critical, die seit 30 Tagen nicht gelaufen sind - Redundanz auf Story-Ebene — zwei Stories mit überlappenden Tests
RF generiert automatisch Tag-Statistiken in output.xml (total / passed / failed / skipped pro Tag). Ein LLM kann diese Statistiken mit Jira-Daten kombinieren und automatisch einen Coverage-Report erzeugen. pytest hat mit @pytest.mark ein ähnliches Konzept, aber die Marker sind im Code eingebettet und müssen per AST-Parsing extrahiert werden. RF-Tags stehen direkt in output.xml — maschinenlesbar ohne Code-Analyse.
Praxisbeispiel — vollständige fachliche Test-Review-Pipeline
Eine LLM-basierte fachliche Test-Review-Pipeline für RF könnte so aussehen.
Schritt 1 — Daten sammeln
Jira-API → Stories + Akzeptanzkriterien für Sprint 42
RF-Parser → Testsuites aus /tests/*.robot
Confluence-API → Fachspezifikation «Registrierungsprozess»
Schritt 2 — LLM-Analyse mit strukturiertem Prompt
Du bist ein Senior QA Engineer. Analysiere die fachliche Qualität
dieser Testsuite.
REQUIREMENTS:
[Jira-Stories + Akzeptanzkriterien einfügen]
TESTSUITE:
[RF-Tests einfügen]
Prüfe:
1. ABDECKUNG: Welche Akzeptanzkriterien haben passende Tests?
Welche sind nicht abgedeckt?
2. REDUNDANZ: Gibt es Tests, die fachlich dasselbe prüfen?
3. TESTDESIGN: Sind für numerische Eingaben Äquivalenzklassen
und Grenzwerte berücksichtigt?
4. FEHLENDE SZENARIEN: Welche fachlichen Szenarien fehlen?
(Negativtests, Edge Cases, Berechtigungen)
Schritt 3 — LLM-Output (Beispiel)
ABDECKUNG:
- AC1 (Reset anfordern) → Test «User Requests Password Reset» (abgedeckt)
- AC2 (Link-Ablauf) → Test «Reset Link Expires After 24 Hours» (abgedeckt)
- AC3 (Passwort-Länge) → Test «New Password Must Meet Minimum Length» (abgedeckt)
- AC4 (Altes Passwort ungültig) → KEIN TEST
- AC5 (Bestätigungs-E-Mail) → KEIN TEST
REDUNDANZ:
- «Verify Login With Valid User» und «Successful Authentication Test»
testen beide denselben Happy Path mit denselben Daten.
TESTDESIGN:
- Passwort-Länge: nur Negativtest für «zu kurz». Fehlend:
- Grenzwert: genau 8 Zeichen (Minimum)
- Grenzwert: 7 Zeichen (eins unter Minimum)
- Äquivalenzklasse: Sonderzeichen, Leerzeichen
- Maximum: Gibt es eine Obergrenze?
FEHLENDE SZENARIEN:
- Was passiert bei ungültiger E-Mail-Adresse beim Reset?
- Was bei mehrfachem Reset-Request hintereinander?
- Rate Limiting für Reset-Requests?
Warum das mit pytest schwieriger wäre
Dieselbe Pipeline mit pytest würde funktionieren, aber:
- Schritt 2 braucht mehr Tokens — der LLM-Kontext muss den gesamten Python-Code enthalten, nicht nur Namen und Keywords.
- Geringere Matching-Genauigkeit —
def test_pw_reset_req()hat weniger semantisches Signal als «User Requests Password Reset Via Email». - Äquivalenzklassen-Analyse erfordert Code-Verständnis — das LLM muss
@pytest.mark.parametrize-Dekoratoren parsen statt eine RF-Datentabelle zu lesen.
Vergleich — RF, pytest und Gherkin für fachliche LLM-Analyse
| Dimension | RF | pytest | Gherkin |
|---|---|---|---|
| Testnamen als fachliche Beschreibung | Standard | optional (oft abgekürzt) | Szenarionamen |
| Keyword-Sequenz lesbar | natürliche Sprache | API-Aufrufe | Given/When/Then |
| Datenwerte sichtbar (Äquivalenzklassen) | Test-Template-Tabelle | parametrize-Tuple | Scenario Outline |
| Tags / Traceability | [Tags] + output.xml | @pytest.mark | @tags in Feature |
| Selbstständig ausführbar | ja | ja | nein (Step Definitions) |
| LLM-Tokens pro Test | rund 75 | rund 130 | rund 50 (Feature) + rund 200 (Steps) |
| Embedding-Qualität (SBERT) | hoch (NL) | niedrig (Code) | hoch (NL, nur Feature) |
| Requirements-Matching | direkt | via Code-Analyse | direkt (nur Feature) |
Gherkin und Cucumber sind für die rein fachliche Bewertung der Feature-Files genauso gut wie RF — oft sogar besser lesbar. Aber: Sobald man prüfen will, ob die Tests tatsächlich das tun, was die Feature-Files versprechen, muss man die Step Definitions analysieren — und die sind Code. RF hat diesen Gap nicht: Was im Test steht, wird ausgeführt.
Grenzen und Gegenargumente
Keyword-Abstraktion als Nachteil. Login To System im RF-Test sagt nichts darüber, ob der Login via UI, API oder Datenbank erfolgt. Für manche fachliche Bewertungen ist das irrelevant (Wird getestet, dass Login funktioniert? Ja). Für andere ist es kritisch (Wird der Login-Flow aus Benutzersicht getestet, oder nur die API?). Ein LLM kann diese Frage aus der .robot-Datei allein oft nicht beantworten — es müsste die Keyword-Implementierung sehen.
Qualität hängt an Keyword-Benennung. RF-Tests sind nur so gut analysierbar, wie die Keywords benannt sind. Step 1, Do Thing, Check Result sind genauso schlecht wie test_001() in pytest. RF erzwingt keine guten Namen.
LLMs halluzinieren bei Test-Bewertung. Wenn ein LLM gefragt wird, ob alle Grenzwerte abgedeckt sind, kann es Grenzwerte erfinden, die im Requirement nicht stehen. Human Review bleibt unverzichtbar.
Kein Tool besetzt die Nische. Stand April 2026 gibt es kein Tool, das RF-Testsuites automatisch gegen Jira, Confluence und PDFs auf fachliche Vollständigkeit prüft. Die Bausteine existieren (Jira-API, RF-Parser, LLM-APIs, Vektor-DBs), aber die Integration fehlt. Das Result-Companion-Tool (PyPI, 2026) analysiert output.xml für Fehler-Ursachen, macht aber keine Requirements-Coverage-Analyse. Testomat.io bietet AI-Duplikaterkennung, aber primär für Cypress und Jest.
Einordnung
RF-Tests fallen direkt in die Kategorie, für die NL-Embeddings und LLMs am besten funktionieren. Für Redundanzerkennung, Requirements-Mapping und Gap-Analyse ist die Hürde niedrig — die Bausteine sind verfügbar, die Forschungsgrundlage ist solide. Was fehlt, ist ein integriertes Tool. Wer eine grosse RF-Suite und gute Akzeptanzkriterien hat, kann mit überschaubarem Aufwand eine eigene Pipeline bauen.
Drei Empfehlungen für den Einsatz: Erstens — Keywords sprechend benennen, weil die Analyse-Qualität an der Benennung hängt. Zweitens — Tags konsequent verwenden, idealerweise mit Jira-IDs als Tag, weil dann Traceability automatisch entsteht. Drittens — Human Review nicht ersetzen, weil LLMs Grenzwerte erfinden können, die nicht spezifiziert sind.
Quellen
- Viggiato et al. — Identifying Similar Test Cases Specified in Natural Language (IEEE TSE 2023)
- Pan et al. — LTM: Scalable Test Suite Minimization based on Language Models (IEEE TSE 2024)
- LLM-as-a-Judge — Scalable Test Coverage Evaluation (arXiv:2512.01232)
- Understanding on the Edge — LLM-generated Boundary Test Explanations (arXiv:2601.22791)
- Rodríguez et al. — LLMs for Unit Tests with Equivalence Partitions and Boundary Values (Springer 2026)
- Ali et al. — RAG + LLM for Requirements Traceability (ER 2024)
- GenIA-E2ETest — Generative AI for E2E Test Automation with Robot Framework
- Xebia — Robot Framework and the Keyword-Driven Approach
- Eficode — AI with Robot Framework
- Robot Framework Forum — Result Companion Tool
Sie wollen RF-Suite und Jira-Stories automatisch auf Abdeckung prüfen oder eine Redundanz-Analyse fahren? Im UTAA-Workshop bewerten wir Pipeline-Architektur, Tooling und Prompt-Strategie projektspezifisch. Mehr zur Methode oder direkt anfragen.