← Alle Artikel

Robot Framework und KI-Codegenerierung

von Rainer Haupt

TL;DR: Robot Frameworks keyword-getriebene Syntax trifft den Sweet Spot für LLM-Generierung — natürlichsprachlich genug, um von den Sprachfähigkeiten der Modelle zu profitieren, gleichzeitig strukturiert genug, um syntaktische Fehler zu minimieren. Konkret braucht ein LLM bei Robot Framework (RF) nur rund fünf Regeln zu beherrschen statt rund 15 bei pytest — und erzeugt rund 40 % weniger Tokens für dieselbe Testlogik. Die Forschung zeigt: Eine DSL mit expliziter, kanonischer Syntax kann selbst ohne Trainingsdaten 99.9 % syntaktisch korrekte Ausgaben erzielen (Anka-Studie, 2024). Die Achillesferse: die unsichtbare Whitespace-Semantik (zwei oder mehr Leerzeichen als Separator) — das genaue Gegenteil dessen, was LLMs gut können.

Lesedauer ca. 13 Min · Stand: 2026-04


Was ein LLM bei pytest richtig machen muss — und bei RF nicht

Der entscheidende Unterschied liegt nicht in der Ausdrucksstärke, sondern in der Fehlerfläche: Wie viele Dinge kann ein LLM falsch machen, bevor der Test nicht mehr läuft?

Bei pytest mit Selenium muss ein LLM Folgendes korrekt generieren: exakte Import-Pfade (from selenium.webdriver.common.by import By — nicht from selenium import By), Fixture-Dekoratoren mit korrektem Scope (@pytest.fixture(scope="module") — nicht scope="test"), die yield-Mechanik für Teardown, conftest.py am richtigen Ort, @pytest.mark.parametrize korrekt buchstabiert (nicht parameterize — ein notorischer LLM-Fehler), die Unterscheidung zwischen assert und self.assertEqual, sowie Plugin-Fixtures wie mocker oder page, die ohne Installation mit «fixture not found» fehlschlagen.

Bei Robot Framework reduziert sich das auf vier Section-Header (*** Settings ***, *** Test Cases ***, *** Keywords ***, *** Variables ***), Library-Namen (Library SeleniumLibrary), Keyword-Namen, die Zwei-Leerzeichen-Regel und Variable-Syntax (${var}). Mehr nicht.

Hier derselbe Login-Test in beiden Frameworks — bei der Menge an «syntaktischem Wissen», die jeweils nötig ist:

Robot Framework:

*** Settings ***
Library    SeleniumLibrary

*** Test Cases ***
Valid Login
    Open Browser    http://localhost:7272    Chrome
    Input Text      username_field    demo
    Input Text      password_field    mode
    Click Button    login_button
    Title Should Be    Welcome Page
    [Teardown]    Close Browser

pytest + Selenium:

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

@pytest.fixture
def browser():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_valid_login(browser):
    browser.get("http://localhost:7272")
    browser.find_element(By.ID, "username_field").send_keys("demo")
    browser.find_element(By.ID, "password_field").send_keys("mode")
    browser.find_element(By.ID, "login_button").click()
    assert browser.title == "Welcome Page"

Der RF-Test braucht rund 75 Tokens, der pytest-Test rund 130 — fast doppelt so viele. Wichtiger noch: Im pytest-Code gibt es mindestens zehn Stellen, an denen ein LLM einen Fehler machen kann, der den Test bricht (falsche Imports, fehlendes yield, falscher By-Selektor, vergessenes driver.quit()). Im RF-Code sind es drei bis vier (falscher Library-Name, falsche Keyword-Schreibweise, fehlendes [Teardown]). Und selbst die Keyword-Schreibweise ist tolerant: Click Button, click_button, CLICK BUTTON und Click_Button funktionieren alle — RF ist case-insensitiv und ignoriert Unterstriche.

Linguistische Gründe — warum LLMs Natursprache besser können als Code-Syntax

Drei Konzepte aus der Computerlinguistik erklären, warum RF für LLMs strukturell vorteilhaft ist.

Semantische Überlappung mit Trainingsdaten. LLMs wurden auf Milliarden Tokens natürlicher Sprache trainiert. RF-Keywords wie Open Browser, Click Button, Page Should Contain oder User Should Be Logged In sind ganz normale englische Sätze. Das Modell hat starke Repräsentationen für diese Wörter und ihre Beziehungen. Wenn ein LLM Click Button login erzeugt, nutzt es dieselben semantischen Verbindungen wie beim Satz «Click the login button». Bei driver.find_element(By.ID, "login-btn").click() muss es dagegen eine spezifische API-Syntax reproduzieren, die nur in einem Bruchteil der Trainingsdaten vorkommt.

Geringe Ambiguität durch kanonische Formen. In Python gibt es viele Wege zum Ziel — ein LLM könnte für einen Login-Test browser.get(), page.goto(), requests.Session(), driver.navigate() oder ein halbes Dutzend anderer APIs erzeugen. RF hat für jede Aktion genau eine kanonische Form: Open Browser, Input Text, Click Button. Die Anka-DSL-Studie (2024) bewies dieses Prinzip: Eine DSL mit expliziter, kanonischer Syntax erzielte 100 % Genauigkeit auf komplexen Aufgaben, während Python bei 60 % stagnierte — ein Vorsprung von 40 Prozentpunkten, und das mit null vorherigem Training auf der DSL.

Flache Grammatik nahe an regulären Sprachen. Die ChomskyBench-Studie (2025) zeigte, dass LLM-Leistung mit zunehmender Komplexität in der Chomsky-Hierarchie abnimmt — reguläre und einfache kontextfreie Sprachen werden besser verarbeitet als kontextsensitive. RFs Grammatik ist nahezu kontextfrei: Sections → Testname → eingerückte Zeilen aus Keyword Argumente. Python dagegen hat kontextsensitive Elemente (Scoping, Indentation-Semantik, Type Inference). RF hat geschätzt 20–30 Grammatikregeln, Python über 100.

Diese drei Faktoren zusammen erklären, warum RF-Keywords als eine Art «API in natürlicher Sprache» funktionieren: Sie nutzen die stärkste Fähigkeit von LLMs (Sprachverständnis) statt ihre schwächste (präzise Syntax-Reproduktion).

Direkter Vergleich — vier Testszenarien in fünf Frameworks

API-Test

Robot Framework:

*** Settings ***
Library    RequestsLibrary

*** Test Cases ***
Get User Details
    ${response}=    GET    https://jsonplaceholder.typicode.com/posts/1
    Status Should Be    200    ${response}
    Should Be Equal As Strings    1    ${response.json()}[id]

pytest + requests:

import requests

def test_get_user_details():
    response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
    assert response.status_code == 200
    assert response.json()["id"] == 1

Cypress:

it('should get user details', () => {
    cy.request('GET', 'https://jsonplaceholder.typicode.com/posts/1')
        .then((response) => {
            expect(response.status).to.eq(200)
            expect(response.body.id).to.eq(1)
        })
})

Bei API-Tests ist der RF-Vorteil kleiner, weil pytest mit requests ebenfalls kompakt ist. Aber: Status Should Be 200 ist selbstdokumentierend, während ein LLM bei pytest wissen muss, ob es assert response.status_code == 200, assert response.ok oder response.raise_for_status() verwenden soll.

Setup und Teardown — wo der Unterschied deutlich wird

Robot Framework:

*** Settings ***
Library           SeleniumLibrary
Suite Setup       Open Browser    ${URL}    Chrome
Suite Teardown    Close Browser
Test Setup        Go To    ${URL}/login

pytest:

@pytest.fixture(scope="module")
def browser():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

@pytest.fixture(autouse=True)
def navigate_to_login(browser):
    browser.get("http://localhost:7272/login")
    yield

RF setzt Setup und Teardown deklarativ — vier Zeilen in den Settings, keine Fixtures, kein yield, kein Scope-Parameter, kein autouse. Ein LLM muss bei pytest die gesamte Fixture-Kaskade verstehen: Was bedeutet scope="module" versus scope="session"? Wann wird yield aufgerufen? Was passiert, wenn Fixture A von Fixture B abhängt? Diese Fragen existieren in RF schlicht nicht.

Datengetriebene Tests — RFs Stärke

Robot Framework mit Test Template:

*** Settings ***
Test Template    Login Should Fail

*** Test Cases ***                USERNAME        PASSWORD
Invalid Username                 invalid         ${VALID PASS}
Invalid Password                 ${VALID USER}   invalid
Both Invalid                     invalid         invalid
Empty Username                   ${EMPTY}        ${VALID PASS}
Empty Password                   ${VALID USER}   ${EMPTY}

*** Keywords ***
Login Should Fail
    [Arguments]    ${username}    ${password}
    Input Text     username_field    ${username}
    Input Text     password_field    ${password}
    Click Button   login_button
    Page Should Contain    Error

pytest mit parametrize:

@pytest.mark.parametrize("username,password", [
    ("invalid", "valid_pass"),
    ("valid_user", "invalid"),
    ("invalid", "invalid"),
    ("", "valid_pass"),
    ("valid_user", ""),
])
def test_login_should_fail(browser, username, password):
    browser.find_element(By.ID, "username_field").send_keys(username)
    browser.find_element(By.ID, "password_field").send_keys(password)
    browser.find_element(By.ID, "login_button").click()
    assert "Error" in browser.page_source

Die RF-Version liest sich wie eine Datentabelle — jede Zeile hat einen eigenen Testnamen und wird als separater Testfall im Report angezeigt. Ein LLM muss nur das Test Template-Konzept kennen. Bei pytest muss es @pytest.mark.parametrize korrekt buchstabieren (häufiger Fehler: parameterize), die Tuple-Syntax in der Liste beherrschen und die String-Parameterübergabe im Dekorator richtig formatieren.

Gherkin ist auch natürlichsprachlich — aber hat ein fundamentales Problem

Gherkin (Cucumber, BDD) ist der offensichtlichste Vergleichspunkt, weil es ebenfalls natürlichsprachlich ist:

Feature: Login
  Scenario: Successful login
    Given the user is on the login page
    When the user enters "admin" as username
    And the user enters "secret" as password
    And the user clicks the login button
    Then the welcome page should be displayed

Das generiert ein LLM mit hoher Zuverlässigkeit — GPT-4 produziert in nur 1 von 50 Feature-Files einen Syntaxfehler (Studie 2024). Aber: Gherkin ist nicht ausführbar. Jeder Schritt braucht eine Step Definition in einer Programmiersprache:

@Given("the user is on the login page")
public void theUserIsOnTheLoginPage() {
    driver.get("http://example.com/login");
}

@When("the user enters {string} as username")
public void theUserEntersUsername(String username) {
    driver.findElement(By.id("username")).sendKeys(username);
}
// ... plus drei weitere Step Definitions

Das ist der Glue-Code-Gap: Das LLM muss in zwei verschiedenen Syntaxwelten gleichzeitig korrekt arbeiten und sie synchronisieren. Die industrielle AutoUAT-Studie (2024, Critical TechWorks / BMW) quantifizierte dieses Problem: LLMs generierten Gherkin-Szenarien mit 95 % Akzeptanzrate, aber die Konvertierung in ausführbare Cypress-Skripte hatte nur 60 % initiale Genauigkeit. Ein Drittel der generierten Tests war sofort unbrauchbar.

RF löst dieses Problem, indem Keywords aus anderen Keywords zusammengesetzt werden — ohne die RF-Syntax zu verlassen:

*** Test Cases ***
Successful Login
    Given The User Is On The Login Page
    When The User Enters Valid Credentials
    Then The Welcome Page Should Be Displayed

*** Keywords ***
The User Is On The Login Page
    Open Browser    ${URL}    ${BROWSER}

The User Enters Valid Credentials
    Input Text    id=username    admin
    Input Text    id=password    secret
    Click Button  id=login-btn

The Welcome Page Should Be Displayed
    Title Should Be    Welcome

Alles in einer Datei, alles in einer Syntax. Kein Sprachwechsel, kein Regex-Pattern-Matching, keine Step-Definition-Dateien. Wo Gherkin den LLM-Vorteil der natürlichen Sprache durch den Glue-Code-Aufwand wieder einbüsst, behält RF ihn durchgehend.

Gherkin hat allerdings einen Vorteil: mehr Trainingsdaten. Cucumber/Gherkin hat etwa 6.5 % Marktanteil versus rund 5 % bei RF (6sense-Daten), und .feature-Dateien sind in Repositories verbreitet. Als reine Spezifikationssprache — Feature-Files ohne Step Definitions — ist Gherkin für LLMs sogar einfacher.

Schwächen — wo RF-Syntax LLMs echte Probleme macht

RF ist kein Paradies für LLM-Generierung. Drei Schwächen wiegen schwer.

Die Whitespace-Falle ist RFs grösstes LLM-Problem. RF verwendet zwei oder mehr Leerzeichen als Spalten-Separator, aber ein einzelnes Leerzeichen ist ein normales Zeichen innerhalb von Keywords und Argumenten. Click Button login (vier Leerzeichen → Keyword + Argument) und Click Button login (ein Leerzeichen → ein einziges, unbekanntes Keyword namens «Click Button login») sehen fast identisch aus, haben aber völlig verschiedene Bedeutungen. LLMs generieren Text Token für Token, und BPE-Tokenizer behandeln Whitespace inkonsistent — mehrere Leerzeichen werden oft zu einem einzelnen Token komprimiert oder unvorhersagbar aufgeteilt. Die RF User Guide räumt selbst ein: «The biggest problem of the space delimited format is that visually separating keywords from arguments can be tricky.» Für LLMs ist das Problem noch gravierender als für Menschen, weil die Unterscheidung unsichtbar ist und RF-Fehlermeldungen nicht auf falsches Spacing hinweisen, sondern auf «wrong arguments». Workaround: Das Pipe-Format (| Keyword | arg1 | arg2 |) macht Separatoren explizit und sichtbar — deutlich LLM-freundlicher.

Weniger Trainingsdaten als Python. RF verwendet .robot-Dateien — eine Nische-Dateiendung, die beim Training von LLMs typischerweise nicht priorisiert wird. Die Grammar-Prompting-Studie (2023) bestätigt: «DSLs are by definition specialized and thus unlikely to have been encountered often enough during pretraining.» Allerdings zeigt die Anka-Studie, dass dieses Problem mit geeignetem Prompting (Few-Shot-Beispiele, Grammatik-Beschreibungen) fast vollständig kompensiert werden kann — eine DSL ohne jegliche Trainingsdaten erreichte 99.9 % Parse-Erfolg.

Variable-Syntax und veraltete APIs. RFs vier Variablen-Präfixe (${scalar}, @{list}, &{dict}, %{env}) sind einzigartig in der Programmierlandschaft. Die Semantik-Unterschiede sind subtil: ${my_list} gibt das Listen-Objekt zurück, @{my_list} entpackt es — Log Many @{my_list} funktioniert, aber Log @{my_list} schlägt fehl, weil das zweite Element als level-Parameter interpretiert wird. Dazu kommt, dass RF 5.0+ RETURN statt [Return] und RF 7.0+ VAR statt Set Variable eingeführt hat — LLMs, die auf älterem Code trainiert wurden, generieren häufig die veraltete Syntax.

Forschung und offene Lücken

Die Evidenzlage ist dünn, aber konsistent. Es existiert kein direkter Benchmark, der LLM-Generierungsqualität über Test-Frameworks hinweg vergleicht — ein gravierender Forschungs-Gap. Was existiert:

Die Sezgin et al. (INFUS 2025)-Studie ist die einzige Arbeit, die explizit LLM-Generierung von RF-Code untersucht. Sie nutzt Retrieval-Augmented Generation (RAG) und bewertet mit CodeBLEU sowie CI/CD-Pass/Fail-Raten. Kernergebnis: RAG-Integration verbesserte Testqualität und -zuverlässigkeit signifikant. Die Anka-DSL-Studie (2024) liefert das stärkste theoretische Argument: Eine DSL mit RF-ähnlichen Eigenschaften (kanonische Formen, explizite Syntax, natürlichsprachliche Keywords) erreichte auf Multi-Step-Aufgaben 100 % Genauigkeit gegenüber 60 % für Python — ohne Training auf der DSL. Die AutoUAT-Studie (2024) zeigt quantitativ den Glue-Code-Gap bei Gherkin: 95 % Szenario-Akzeptanz, aber nur 60 % ausführbare Skripte.

Aus der Community gibt es praxisnahe Evidenz: Im Robot Framework Forum berichten Nutzer von erfolgreicher Testgenerierung mit VS Code + Copilot (Agent Mode, Claude Sonnet 4) in Kombination mit MCP-Servern für Library-Dokumentation. Der RF-MCP-Server (Many Kasiriha, vorgestellt auf der RoboCon 2026) adressiert das Halluzinations-Problem gezielt, indem er LibDoc nutzt, um dem LLM nur tatsächlich existierende Keywords bereitzustellen. Auf der RoboCon 2026 widmeten sich 8 von rund 20 Sessions explizit dem Thema AI + RF — ein Zeichen, wie zentral das Thema für die Community geworden ist.

Einordnung — RFs Token-effiziente Nische in der LLM-Ära

DimensionRobot FrameworkpytestGherkin / Cucumber
Tokens für Login-Testrund 75rund 130rund 50 (Feature) + rund 200 (Steps)
Fehlerquellen pro Testrund 5über 15rund 3 (Feature) + rund 15 (Steps)
Case-sensitivNeinJaTeilweise
Selbstständig ausführbarJaJaNein (braucht Glue-Code)
NatürlichsprachlichHochNiedrigSehr hoch (nur Feature)
Trainingsdaten-AbdeckungGeringHochMittel
Whitespace-RisikoHochNiedrigKeins

Die Kernthese lässt sich auf einen Satz reduzieren: RF minimiert die Distanz zwischen dem, was ein LLM natürlicherweise erzeugt (natürliche Sprache), und dem, was die Maschine ausführen kann (formale Testlogik). Keine andere Test-Syntax trifft diesen Sweet Spot so gut. pytest ist mächtiger, aber syntaktisch fragiler. Gherkin ist natürlichsprachlicher, aber nicht selbstständig ausführbar. Cypress und Playwright sind modern, verlangen aber vollständige Programmiersprachen-Kompetenz.

RFs echte Innovation für die LLM-Ära ist nicht, dass es einfach ist — sondern dass es fehlertolerant ist. Case-Insensitivität, Underscore-Ignoranz und die keyword-getriebene Abstraktion schaffen einen breiten Korridor, in dem ein LLM «ungefähr richtig» liegen kann und der Test trotzdem läuft. Bei pytest muss alles exakt stimmen. Bei RF reicht «nah genug» oft aus — und genau das ist, was probabilistische Sprachmodelle am besten können.

Quellen


Sie evaluieren KI-gestützte Testgenerierung für ein bestehendes RF-Setup oder vergleichen Frameworks unter LLM-Aspekt? Im UTAA-Workshop bewerten wir Toolchain, Prompt-Strategie und MCP-Integration projektspezifisch. Mehr zur Methode oder direkt anfragen.

Rückruf anfordern