What is Magento MFTF?
Short answer
MFTF is the Magento Functional Testing Framework, Adobe’s own end-to-end (E2E) UI test runner for Magento 2 and Adobe Commerce. You write tests in XML, not PHP, and MFTF turns them into Codeception tests that drive a real browser through Selenium / Chromedriver. Tests sit in <Module>/Test/Mftf/ inside each module. It came in around Magento 2.2 (2018) to replace the older Selenium suite, Magento core ships thousands of these tests, and it is part of what Adobe checks for Marketplace EQP. I write MFTF tests mostly for extensions and for checkout flows I do not want to click through by hand after every upgrade.
- Write test XML in your module 01
- Reuse ActionGroups for common flows 02
- Pin selectors in Section files 03
- Run the test from the CLI 04
- Wire JUnit output into CI 05
Most common mistake Selectors pinned to unstable CSS classes
Five steps from first test XML to CI integration
MFTF is an XML format with Codeception doing the real work underneath. This is how the pieces fit, from the first test file to a CI report.
-
01
Write test XML in your module
A new test goes in
<Vendor>/<Module>/Test/Mftf/Test/MyFeatureTest.xml. The file holds a<test>element with annotations (stories, title, severity, group) and a list of steps. You never write a PHP class for it.vendor/bin/mftf generate:testsreads the XML and writes the Codeception PHP for you. -
02
Reuse ActionGroups for common flows
ActionGroups live under
<Module>/Test/Mftf/ActionGroup/*.xmland are reusable chunks of steps.AdminLoginActionGrouplogs into the admin,StorefrontAddProductToCartActionGroupadds a product to the cart. You call them with<actionGroup ref="AdminLoginActionGroup" stepKey="login"/>. Most of my own tests are a handful of core ActionGroups plus two or three steps specific to the module. -
03
Pin selectors in Section files
CSS and XPath selectors go in
<Module>/Test/Mftf/Section/MySection.xml, away from the test steps. When an admin screen changes markup, you fix the selector once in the Section file instead of in every test that clicks it. Where the template has a stable attribute such asdata-roleor anid, I use that rather than a styling class. -
04
Run the test from the CLI
Run one test with
vendor/bin/mftf run:test MyFeatureTest, or a whole group withvendor/bin/mftf run:group myGroup. MFTF regenerates the tests, starts the browser session through Selenium, runs every step and reports pass or fail. The same XML runs on my laptop, in a CI container or against a Selenium Grid. -
05
Wire JUnit output into CI
Results land in
dev/tests/acceptance/tests/_output/, with a screenshot and an HTML dump of the page for every failed step. I upload that folder as a build artefact in GitHub Actions or GitLab CI, so when a test fails I can see what the browser saw instead of guessing.
Four situations where MFTF is the obvious answer
I do not reach for MFTF on every project. These are the four cases where I think it is clearly worth the setup.
-
Magento Marketplace EQP review
Every extension submitted to the Magento Marketplace goes through the Extension Quality Program (EQP) review. As part of the technical review Adobe runs its own MFTF tests against your extension on each supported PHP version, and it also runs any MFTF tests you include in the package. Shipping at least one happy-path MFTF test per public-facing feature catches the breakage Adobe’s tests would find, before you wait in the review queue.
-
Regression-testing custom modules across upgrades
A minor upgrade (2.4.7 to 2.4.8, say) tends to break custom code in small, quiet ways: a core class signature changes, an admin form moves, a GraphQL field behaves differently. An MFTF suite run against the upgraded code finds those before customers do. I run it after every
composer updateofmagento/product-community-edition. -
Large team / agency Magento builds
On bigger teams MFTF lets QA people write browser tests in XML without learning PHP or the Selenium API. QA writes the test against staging, a developer reviews the XML in the pull request, and it joins the suite. PHPUnit unit tests stay with the developers, MFTF tests are shared with QA.
-
Hardening pre-production releases
Before pushing a major feature to production, run a smoke MFTF suite against staging that covers the critical paths: checkout, account creation, password reset, admin login, product save, order processing. Combine with PHPUnit for unit-level coverage. The two together (MFTF for E2E + PHPUnit for units) is the Adobe-recommended testing stack and gives the highest confidence before a Friday-night deploy.
Three MFTF misconfigs that waste weeks of QA time
Almost every flaky-MFTF-suite I have been called in to fix came from one of these three mistakes. Audit your tests for them today.
-
Selectors pinned to unstable CSS classes
The Magento admin DOM changes every minor version:
.admin__data-grid-headerin 2.4.5 becomes.admin-grid-headerin 2.4.7, and your entire MFTF suite goes red. Pin selectors todata-testordata-mage-initattributes where they exist, fall back to semanticaria-labelmatches, and treat raw CSS classes as a last resort. Centralise them all in Section XML so a DOM rewrite is a one-file fix. -
Running MFTF against production mode
MFTF needs Magento in developer mode (or at least a fresh
setup:static-content:deployrun) so the theme assets are compiled and the test runner can drive the rendered DOM. Running against a production-mode site without static-content deployed gives missing-asset 404s, broken layouts, and false-negative test failures. Runbin/magento deploy:mode:set developeron your CI Magento container before any MFTF run. -
Mixing MFTF + PHPUnit + Cypress randomly
Three E2E frameworks in one module is a maintenance nightmare: every selector lives in three places, every fixture is duplicated, every CI run takes 4× as long. Pick one E2E framework per module. MFTF is the Adobe-blessed choice and integrates with Magento Marketplace EQP automatically. PHPUnit stays for unit tests (different layer, different job). Drop Cypress / Playwright unless you have a non-Magento frontend layer that already uses it.
Magento MFTF: frequently asked questions
-
MFTF vs PHPUnit: what is the difference?
They sit at different layers of the testing pyramid and solve different problems. PHPUnit is a unit-test framework: it instantiates a single PHP class in isolation, mocks its dependencies, and asserts behaviour at the method level. Tests are fast (milliseconds), deterministic, and run with the Magento application bootstrap but without a browser. MFTF is an end-to-end test framework: it drives a real Chromedriver browser against a running Magento install, clicks through real DOM elements, and asserts full-flow behaviour like "an admin can save a configurable product with three variants and the storefront then renders all three swatches." Tests are slow (~30 seconds each), realistic, and catch integration bugs PHPUnit can't see. Use both: PHPUnit for unit coverage, MFTF for E2E happy-path coverage. -
MFTF vs Cypress or Playwright: why not those?
Cypress and Playwright are excellent generic browser-test frameworks for any web app: fast, modern, good developer ergonomics. They are not Magento-aware. MFTF is Adobe-blessed, ships with Magento out of the box (vendor/bin/mftfis part of the magento/magento2-functional-testing-framework package), and integrates directly with Magento Marketplace EQP: your tests get re-run by Adobe’s reviewers when you submit an extension. MFTF also has built-in support for Magento entities (create a category fixture, create a customer fixture, create an order fixture) without you wiring up the data. For a Magento-only project pick MFTF. For a hybrid project (Magento backend + React storefront), Cypress / Playwright covers the React side and MFTF covers the Magento admin. -
Can I write MFTF tests in PHP?
No, by design: MFTF tests are XML only. The whole point is to make tests writable by QA non-developers and reviewable by anyone who can read XML. There are PHP escape hatches for cases the XML grammar can't express: Helper classes in<Module>/Test/Mftf/Helper/*.phplet you call arbitrary PHP from a test step (useful for setting up complex fixtures or hitting external APIs from a test), and Custom Actions let you extend the action vocabulary. Use them sparingly: every PHP escape hatch is a piece of test logic that lives outside the XML and breaks the "QA can read the test" promise. If you find yourself writing 200 lines of PHP per MFTF test, you probably want PHPUnit instead. -
Does MFTF work on Hyvä storefronts?
Yes, with one caveat. MFTF admin tests (which is the bulk of any test suite: order processing, product saves, customer admin, configuration changes) work identically on Hyvä sites because Hyvä only replaces the storefront theme, not the admin. MFTF storefront tests need updated Section selectors because Hyvä uses Alpine.js + Tailwind utility classes instead of KnockoutJS + RequireJS: the DOM structure is completely different. Most teams keep two storefront Section files: one for Luma, one for Hyvä, and switch via test groups. The Hyvä team also ships a hyva-themes/hyva-mftf companion package with pre-built Hyvä sections, which saves a few days of selector authoring. -
How long does an MFTF suite take to run?
Roughly 30 seconds per test as a working rule of thumb, that includes the browser cold start, Magento bootstrap, fixture creation, the test steps themselves, and screenshot/cleanup. The Magento core test suite at 12,000+ tests takes around 6 hours in Adobe’s CI, split across parallel Selenium Grid workers. For your own custom module, a focused 50-test smoke suite runs in 25-30 minutes single-threaded, or 5-8 minutes if you parallelise across 5 CI workers. Don't try to run the full suite on every PR, tag tests with severity groups (critical, normal, low) and run only critical on PR, full suite nightly. That keeps CI feedback fast without sacrificing coverage. -
Can MFTF run against production?
Strongly discouraged, MFTF tests create test products, place test orders, create test customers, and modify configuration as part of their setup. Running them against production means real customers see "MFTF Test Product 1234" in your catalogue, real orders get test-customer entries in your fulfilment queue, and real stock levels get decremented by checkout-flow tests. Always run MFTF against staging, CI, or a dedicated test environment that mirrors production but is isolated from real traffic. If you need to verify production behaviour after a deploy, use a small read-only smoke check (curl the storefront, hit the admin login page, check robots.txt), not MFTF. MFTF is for environments you’re willing to write to.
Want MFTF tests written for your Magento module?
Send your repo and feature list: I will scope an MFTF suite (critical happy paths, EQP-pass coverage, CI wiring) and reply with a written test plan, fixed-price quote, and earliest start date. 24-business-hour turnaround.