XML-basierte Tests für Magento Core und Module
Dieser Artikel erklärt, was das Magento Functional Testing Framework technisch leistet, wie sich seine deklarative XML-Struktur grundlegend von imperativem Cypress oder Playwright Code unterscheidet, und in welchen Projektphasen MFTF weiterhin die richtige Wahl bleibt. Entwickler erhalten eine klare Einordnung, wann Backend-Tests mit MFTF sinnvoller sind als moderne JavaScript E2E Tests für die Storefront.
Inhaltsverzeichnis
- 1. Was ist MFTF und welche Rolle spielt es im Magento-Ökosystem
- 2. MFTF im Vergleich zu Cypress und Playwright: deklarativ statt imperativ
- 3. Die MFTF-Architektur: Test, ActionGroup, Data, Page und Section
- 4. Generierter Code: wie MFTF aus XML PHP und Codeception erzeugt
- 5. Wann MFTF auch heute noch die richtige Wahl ist
- 6. Wann ein modernes JS E2E Tool die bessere Wahl ist
- 7. Ein konkretes MFTF-Testbeispiel im Detail
- 8. MFTF-Tests generieren und ausführen
- 9. MFTF und Cypress/Playwright im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Was ist MFTF und welche Rolle spielt es im Magento-Ökosystem
Das Magento Functional Testing Framework (MFTF) ist das offizielle Testframework von Adobe für funktionale Akzeptanztests in Magento 2 und Adobe Commerce. Es liegt jedem Magento-Core-Release bei, deckt Kernfunktionalität wie Checkout, Produktverwaltung, Kundenkonten und Adminbereich ab, und wird von Adobe selbst zur Regressionsabsicherung des Plattform-Codes eingesetzt. Wer ein Modul entwickelt, das mit Core-Verhalten interagiert, findet in dev/tests/acceptance tausende bestehende Tests als Referenz und Erweiterungsbasis.
Anders als generische E2E-Frameworks ist MFTF explizit auf die Magento-Domäne zugeschnitten: Es kennt Konzepte wie Admin-Grids, Layered Navigation, Multi-Website-Setups und ACL-Rollen bereits als wiederverwendbare Bausteine. Für Agenturen, die Drittanbieter-Module warten oder eigene Erweiterungen für den Marketplace einreichen, ist MFTF deshalb kein optionales Werkzeug, sondern Teil des erwarteten Qualitätsnachweises gegenüber Adobe und der Community.
2. MFTF im Vergleich zu Cypress und Playwright: deklarativ statt imperativ
Der fundamentale Unterschied liegt im Programmiermodell: Cypress und Playwright sind imperativ, ein Test ist JavaScript- oder TypeScript-Code, der Schritt für Schritt beschreibt, was passieren soll, inklusive Bedingungen, Schleifen und beliebiger Logik. MFTF ist deklarativ: Ein Test wird als XML-Dokument definiert, das eine Abfolge benannter Aktionen beschreibt, ohne dass der Testautor eine general-purpose Programmiersprache beherrschen muss. Diese Entscheidung senkt die Einstiegshürde für QA-Teams ohne tiefe JavaScript-Kenntnisse spürbar.
MFTF bringt zudem ein eigenes, Magento-spezifisches Vokabular an Actions mit, etwa fillField, waitForPageLoad oder seeInCurrentUrl, kombiniert mit vordefinierten Sections für Standard-Seiten wie das Admin-Login oder das Produktformular. Cypress und Playwright kennen dieses Vokabular nicht, jede Selektor-Logik und jedes Warteverhalten muss projektseitig selbst implementiert werden. Das macht moderne JS-Tools flexibler, aber ohne eine eigene Utility-Bibliothek auch deutlich redundanter bei Magento-typischen Abläufen wie dem Admin-Login oder dem Speichern eines Produkts.
3. Die MFTF-Architektur: Test, ActionGroup, Data, Page und Section
MFTF strukturiert Tests in fünf XML-Dateitypen, die klar getrennte Verantwortlichkeiten haben. Eine Section definiert Selektoren für UI-Elemente einer Seite, eine Page definiert die URL und referenziert zugehörige Sections. Eine ActionGroup bündelt wiederkehrende Interaktionsfolgen, etwa den kompletten Admin-Login, zu einem parametrisierbaren, wiederverwendbaren Baustein. Ein Test orchestriert schließlich ActionGroups und einzelne Actions zu einem vollständigen Testszenario mit Vor- und Nachbereitung. Data-XML-Dateien liefern schließlich Testdaten-Entities, die in Tests per Referenz eingebunden werden, statt Werte hart zu codieren.
Diese modulare Trennung zahlt sich bei großen Testsuiten aus: Ändert sich ein CSS-Selektor im Admin-Produktformular, muss nur die betroffene Section angepasst werden, alle Tests und ActionGroups, die diese Section referenzieren, bleiben unverändert lauffähig. Die beiden folgenden Beispiele zeigen eine ActionGroup für den Admin-Login und die zugehörige Section mit den referenzierten Selektoren.
<?xml version="1.0" encoding="UTF-8"?>
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminLoginActionGroup">
<annotations>
<description>Logs in to the Magento Admin Panel with valid credentials.</description>
</annotations>
<arguments>
<argument name="username" defaultValue="{{_ENV.MAGENTO_ADMIN_USERNAME}}"/>
<argument name="password" defaultValue="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/>
</arguments>
<amOnPage url="{{AdminLoginPage.url}}" stepKey="navigateToAdminLogin"/>
<waitForPageLoad stepKey="waitForLoginPage"/>
<fillField selector="{{AdminLoginFormSection.username}}" userInput="{{username}}" stepKey="fillUsername"/>
<fillField selector="{{AdminLoginFormSection.password}}" userInput="{{password}}" stepKey="fillPassword"/>
<click selector="{{AdminLoginFormSection.signInButton}}" stepKey="clickSignIn"/>
<waitForPageLoad stepKey="waitForDashboard"/>
</actionGroup>
</actionGroups>
<?xml version="1.0" encoding="UTF-8"?>
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
<section name="AdminLoginFormSection">
<element name="username" type="input" selector="#username"/>
<element name="password" type="input" selector="#login"/>
<element name="signInButton" type="button" selector="button.action-login"/>
</section>
<section name="AdminProductGridSection">
<element name="productNameCell" type="text" selector="td.col-name" parameterized="true"/>
<element name="successMessage" type="text" selector="div.message-success"/>
</section>
</sections>
4. Generierter Code: wie MFTF aus XML PHP und Codeception erzeugt
MFTF ist selbst kein Testrunner, sondern eine Codegenerierungsschicht über Codeception, PHPs bekanntestem Akzeptanztest-Framework. Beim Aufruf von vendor/bin/mftf generate:tests liest MFTF alle XML-Dateien aus Test/Mftf/Test, ActionGroup, Section, Page und Data ein, löst Referenzen und Merges zwischen Modulen auf, und erzeugt daraus konkrete PHP-Klassen im Verzeichnis dev/tests/acceptance/tests/_generated. Jede dieser Klassen ist ein regulärer Codeception-Cest, der die Selenium- oder Chromedriver-WebDriver-API nutzt.
Dieser Zwischenschritt hat einen entscheidenden praktischen Effekt: Der generierte Code ist kein Implementierungsdetail, das man ignorieren kann, sondern bei Debugging-Sessions oft der schnellste Weg, um zu verstehen, warum ein Test fehlschlägt, weil Stacktraces auf konkrete Zeilen im generierten PHP zeigen. Entwickler sollten den generierten Code niemals manuell editieren, da er bei jedem erneuten generate:tests überschrieben wird, ihn aber durchaus als Debugging-Hilfsmittel lesen.
5. Wann MFTF auch heute noch die richtige Wahl ist
MFTF bleibt dort erste Wahl, wo Tests eng an Magento-Core- oder Modul-Interna gekoppelt sind: Admin-Workflows, ACL-Berechtigungen, komplexe Produkttyp-Konfigurationen, Multi-Source-Inventory oder das Zusammenspiel mehrerer Drittanbieter-Module im Backend. Wer ein Modul für den Adobe Commerce Marketplace einreicht, kommt an MFTF-Tests praktisch nicht vorbei, da die Marketplace-Qualitätsrichtlinien funktionale Testabdeckung explizit als Freigabekriterium listen und Reviewer bestehende MFTF-Suiten als Referenzpunkt nutzen.
Auch als Regressionsnetz gegen zukünftige Magento-Core-Updates ist MFTF wertvoll: Da Adobe selbst tausende MFTF-Tests gegen jedes neue Core-Release laufen lässt, profitieren Modul-Entwickler von derselben Testinfrastruktur und können eigene Suiten in denselben CI-Lauf integrieren. Für Agenturen mit mehreren Bestandskunden auf klassischen, nicht auf Hyvä migrierten Themes ist MFTF zudem oft die einzige praktikable Option, weil UI-Komponenten und Knockout.js-Widgets bereits mit passenden Sections abgedeckt sind, für die ein neu aufgesetztes JS-Test-Setup erst mühsam nachgebaut werden müsste.
6. Wann ein modernes JS E2E Tool die bessere Wahl ist
Für die Storefront eines Hyvä-Shops kehrt sich die Empfehlung um. Hyvä setzt konsequent auf Tailwind CSS und Alpine.js, ein Frontend-Stack, für den es in MFTF weder vordefinierte Sections noch Kenntnis der Alpine-internen State-Verwaltung gibt. Jede Interaktion mit einem x-data-Komponentenstatus müsste in MFTF über generische CSS-Selektoren nachgebildet werden, während Cypress oder Playwright direkt im selben Browser-Kontext arbeiten, in dem auch echte Nutzer interagieren, und dabei von einer aktiven, gut gepflegten Tooling-Community profitieren.
Auch der Feedback-Loop spricht klar für JS-Tools: Ein Cypress-Test läuft in Sekunden im interaktiven Watch-Modus mit Time-Travel-Debugging und Live-DOM-Snapshots, während ein MFTF-Test erst generiert und dann über eine vollständige Selenium-Session ausgeführt werden muss, was pro Testlauf spürbar mehr Zeit kostet. Playwright ergänzt das um native Cross-Browser-Unterstützung, Netzwerk-Mocking und visuelle Regressionstests mit Pixel-Vergleich, allesamt Funktionen, die im MFTF-Ökosystem nicht oder nur über Umwege verfügbar sind.
7. Ein konkretes MFTF-Testbeispiel im Detail
Das folgende Beispiel zeigt einen vollständigen MFTF-Test, der als Admin-Nutzer ein einfaches Produkt anlegt und die Erfolgsmeldung prüft. Der annotations-Block dokumentiert Feature, Story, Titel, Beschreibung und Schweregrad, Metadaten, die MFTF unter anderem zur Testselektion nach Gruppe nutzt. Der before-Block referenziert die zuvor gezeigte AdminLoginActionGroup, sodass der Login-Ablauf nicht in jedem Test erneut ausgeschrieben werden muss.
Der eigentliche Testkörper füllt Formularfelder über referenzierte Section-Selektoren, klickt den Speichern-Button und prüft mit see, ob die erwartete Erfolgsmeldung im DOM erscheint, funktional vergleichbar mit assertSee in klassischen Codeception-Tests. Der after-Block sorgt für sauberen Logout am Testende, unabhängig davon, ob der Test erfolgreich war oder fehlgeschlagen ist.
<?xml version="1.0" encoding="UTF-8"?>
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="AdminCreateSimpleProductTest">
<annotations>
<features value="Catalog"/>
<stories value="Create Product"/>
<title value="Admin can create a simple product"/>
<description value="Verifies that an admin user can create a simple product and see the success message."/>
<severity value="CRITICAL"/>
<group value="catalog"/>
</annotations>
<before>
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
</before>
<amOnPage url="{{AdminProductNewPage.url}}" stepKey="navigateToNewProduct"/>
<waitForPageLoad stepKey="waitForProductForm"/>
<fillField selector="{{AdminProductFormSection.productName}}" userInput="Test Product 123" stepKey="fillProductName"/>
<fillField selector="{{AdminProductFormSection.productSku}}" userInput="test-product-123" stepKey="fillProductSku"/>
<fillField selector="{{AdminProductFormSection.productPrice}}" userInput="19.99" stepKey="fillProductPrice"/>
<click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSave"/>
<waitForPageLoad stepKey="waitForSave"/>
<see selector="{{AdminProductGridSection.successMessage}}" userInput="You saved the product." stepKey="assertSuccessMessage"/>
<after>
<actionGroup ref="AdminLogoutActionGroup" stepKey="logoutAsAdmin"/>
</after>
</test>
</tests>
8. MFTF-Tests generieren und ausführen
Der MFTF-Workflow läuft immer zweistufig ab: erst Generierung, dann Ausführung. vendor/bin/mftf generate:tests übersetzt sämtliche XML-Quellen in PHP und legt sie im generierten Verzeichnis ab, optional eingeschränkt auf eine bestimmte Testgruppe oder ein einzelnes Modul. Erst danach kann Codeception die generierten Tests tatsächlich gegen eine laufende Magento-Instanz und einen konfigurierten Selenium- oder Chromedriver-Endpunkt ausführen.
Für die tägliche Entwicklungsarbeit lohnt sich ein enger, gezielter Zyklus: einen einzelnen Test oder eine Gruppe generieren und ausführen, statt bei jeder Änderung die komplette Suite neu zu bauen, was bei größeren Modulen mehrere Minuten dauern kann. Die Umgebungskonfiguration in .env und MFTF-spezifischen Konfigurationsdateien steuert dabei Basis-URL, Admin-Zugangsdaten und den Browser-Endpunkt zentral für das gesamte Projekt.
# Generate the PHP/Codeception test suite from MFTF XML sources
vendor/bin/mftf generate:tests
# Run a single generated test against the configured Selenium/WebDriver
vendor/bin/mftf run:test AdminCreateSimpleProductTest
# Run an entire test group, e.g. all catalog-related tests
vendor/bin/mftf run:group catalog
# Regenerate and run in one step, cleaning stale generated code first
vendor/bin/mftf generate:tests --force
vendor/bin/mftf run:test AdminCreateSimpleProductTest --remove
9. MFTF und Cypress/Playwright im direkten Vergleich
Beide Ansätze sind in ihrem jeweiligen Kontext berechtigt, die folgende Tabelle stellt die wichtigsten Entscheidungsdimensionen gegenüber. Wichtig dabei: Keine Zeile bedeutet, dass ein Tool grundsätzlich schlechter ist, sondern nur, in welchem Szenario es strukturell im Nachteil ist.
| Aspekt | MFTF | Cypress/Playwright | Empfehlung |
|---|---|---|---|
| Sprache/Ansatz | Deklaratives XML, ungewohnt für Frontend-Teams | JS/TS, vertraute Syntax | JS-Tools für Frontend-Devs bevorzugen |
| Feedback-Loop | Generierung + volle Selenium-Session | Sekundenschnell, Watch-Modus | Cypress/Playwright für schnelle Iteration |
| Magento-Vokabular | Riesige Library an Actions/Sections | Muss projektseitig selbst gebaut werden | MFTF für Core-nahe Tests nutzen |
| Marketplace-Compliance | Erwarteter Qualitätsnachweis | Kein Teil des offiziellen Prozesses | MFTF für Modul-Einreichungen |
| Hyvä-Storefront-Tests | Kein Wissen über Alpine.js-State | Native Browser-Interaktion, visuelle Regression | Cypress/Playwright für Storefront-E2E |
Als Kontrastbeispiel zeigt der folgende Code denselben Grundgedanken eines Erfolgsnachweises nach einer Aktion, hier als Playwright-Test für einen Warenkorb-Flow auf einer Hyvä-Storefront, deutlich kompakter als das äquivalente MFTF-XML, aber ohne dessen eingebautes Magento-Vokabular.
import { test, expect } from '@playwright/test';
// Equivalent storefront flow written imperatively for a Hyvä theme frontend
test('customer can add a simple product to the cart', async ({ page }) => {
await page.goto('/test-product-123.html');
await page.getByRole('button', { name: 'Add to Cart' }).click();
// Hyvä updates the mini cart via Alpine.js state, no full page reload
await expect(page.locator('[data-cart-count]')).toHaveText('1');
await expect(page.getByText('You added Test Product 123 to your shopping cart.')).toBeVisible();
});
In der Praxis fahren die meisten Magento-Projekte am besten mit einer bewussten Aufteilung: MFTF für Regressionstests im Backend, bei Modul-Integrationen und wo Marketplace-Compliance verlangt wird, Cypress oder Playwright für alles, was Kunden im Hyvä-Frontend tatsächlich sehen und bedienen. Diese Trennung vermeidet doppelte Testabdeckung und nutzt beide Werkzeuge dort, wo sie strukturell im Vorteil sind.
Mironsoft
MFTF, Cypress und Playwright Teststrategie für Magento- und Hyvä-Projekte
Eine belastbare Teststrategie für euer Magento-Projekt?
Wir bauen MFTF-Suiten für Backend- und Modul-Regression auf, richten Cypress oder Playwright für eure Hyvä-Storefront ein und verzahnen beide in einer CI/CD-Pipeline, die schnelles Feedback mit belastbarer Abdeckung verbindet.
MFTF-Testsuiten
Admin-, Modul- und Marketplace-Compliance-Tests aufbauen
Hyvä-Storefront-E2E
Cypress/Playwright für Checkout- und Kaufflows einrichten
CI/CD-Integration
Beide Testebenen automatisiert in eure Pipeline einbinden
10. Zusammenfassung
MFTF löst ein anderes Problem als Cypress oder Playwright: Es beschreibt Tests deklarativ in XML, generiert daraus PHP-Code für Codeception, und bringt ein umfangreiches, Magento-spezifisches Vokabular an Actions und Sections für Backend- und Modul-Tests mit. Die Architektur aus Test, ActionGroup, Data, Page und Section erlaubt saubere Wiederverwendung über große Testsuiten hinweg, allerdings auf Kosten eines langsameren Feedback-Loops im Vergleich zu modernen JavaScript-Tools.
Für die Storefront eines Hyvä-Shops bleibt ein modernes E2E-Tool die bessere Wahl, weil es direkt im selben Browser-Kontext arbeitet wie echte Kunden, schnelleres Feedback liefert und Alpine.js-Interaktionen nativ versteht. Die pragmatischste Lösung für die meisten Magento-Projekte ist keine Entweder-oder-Entscheidung, sondern eine bewusste Kombination: MFTF für Core- und Modul-Regression, ein JS-Tool für alles, was Kunden im Frontend tatsächlich erleben.
MFTF und moderne E2E-Tools - Das Wichtigste auf einen Blick
XML statt JavaScript
MFTF beschreibt Tests deklarativ und generiert daraus lauffähigen PHP/Codeception-Code.
Modulare Architektur
Test, ActionGroup, Data, Page und Section greifen wiederverwendbar ineinander.
Einsatzbereich MFTF
Core-/Modul-Regression, Admin-Workflows und Marketplace-Qualitätsgates.
Einsatzbereich Cypress/Playwright
Hyvä-Storefront, schnelle Iteration, visuelle Regression und Cross-Browser-Tests.