World’s largest virtual agentic engineering & quality conference

WHENAUG 19-21
WHEREVirtual · Global
Register Now
Mobile App Testing

Maestro Testing: Mobile UI Automation With YAML Flows

Maestro testing explained: write mobile UI tests as YAML flows, the command set, Maestro vs Appium, and how to run flows across real devices from one config.

Author

Bhawana

Author

Last Updated on: August 8, 2026

Most mobile suites die of setup cost. A driver session, a build step, a page object layer, and a dependency tree stand between a team and its first passing test, and plenty of apps never get past that to any automated coverage at all.

Maestro removes that entire preamble by making a test a YAML file. This guide covers Maestro testing end to end: the command set, how it compares with Appium, and the parts that get harder rather than easier, using flows and configuration taken from a working Maestro setup.

Overview

Maestro testing means writing mobile UI tests as declarative YAML flows instead of code. A flow names the app under test, then lists ordered commands such as launchApp, tapOn, inputText, and assertVisible. It supports Android, iOS, React Native, and Flutter, and it runs without a compile step or a driver session.

What Makes Maestro Different?

  • YAML instead of code: A flow is a readable list of steps, so a product manager can review one and a tester can write one without setting up a project.
  • Built-in waiting: Commands wait for the interface to settle before acting, which removes the explicit sleeps that make hand-written mobile suites brittle.
  • No build step: Flows are interpreted at run time, so editing a test and rerunning it is immediate rather than a compile cycle.
  • Limited control flow: The same declarative design that makes flows readable makes loops, branching, and shared logic awkward, which is the main reason large suites stay in Appium.

How Do You Run It at Scale?

Locally Maestro drives the devices attached to your machine. Running flows across many real device models means executing them on a cloud grid, which on TestMu AI is done through HyperExecute with a single configuration file that uploads the build, selects devices, and invokes Maestro on the runner.

What Is Maestro?

Maestro testing is built on one idea: a test is a declarative YAML document rather than a program. You state which application the flow applies to, then list the steps in order. The runtime interprets that file against a connected device or emulator.

The design choice underneath is that mobile UI tests are mostly sequences of taps, inputs, and assertions, and that expressing those in a general-purpose language costs more than it returns for the common case. Removing the language removes the project scaffolding with it.

The second design choice matters more in practice. Every command waits for the interface to be ready before acting, rather than executing immediately and leaving the author to guess at sleeps. Hand-written mobile automation accumulates fixed waits precisely because that guessing is hard, and those waits are what make suites slow and flaky at the same time.

Which Maestro You Mean

Worth settling early, because searching for this tool returns two unrelated products and a great deal of music software.

NameWhat it isWho it is for
Maestro (this article)Open-source mobile UI testing framework driving Android and iOS apps from YAML flows.Mobile QA engineers and developers automating app journeys.
Opkey MaestroA commercial agentic orchestration layer for enterprise application lifecycles across systems such as Oracle and Workday.Enterprise programme and ERP teams.

The two share a word and nothing else. Everything below refers to the mobile testing framework.

Your First Flow

A flow has two parts separated by a document break: a header naming the application, and an ordered list of commands. This one walks the Wikipedia app through its onboarding screens.

appId: org.wikipedia
---
- launchApp
- tapOn:
    id: "org.wikipedia:id/fragment_onboarding_forward_button"
- tapOn:
    id: "org.wikipedia:id/fragment_onboarding_forward_button"
- tapOn:
    id: "org.wikipedia:id/fragment_onboarding_forward_button"
- tapOn:
    id: "org.wikipedia:id/fragment_onboarding_done_button"

That is the whole test. No imports, no driver configuration, no build. A flow using visible text instead of view ids reads even more plainly, which is what makes these files reviewable by people who will never open an IDE.

appId: com.example.contacts
---
- launchApp
- tapOn: "Create new contact"
- tapOn: "First Name"
- inputText: "John"
- tapOn: "Last Name"
- inputText: "Snow"
- tapOn: "Save"
- assertVisible: "Add Phone Number"

Run it against an attached device or emulator with a single command. The framework resolves the app, installs it if needed, and executes the steps in order.

maestro test flow_contacts_android.yaml

Selectors and Commands

The command vocabulary is deliberately small. These cover the overwhelming majority of flows.

CommandWhat it doesNote
launchAppStarts the app named in the header.Accepts a flag to clear state first, which is what makes a flow independent of the one before it.
tapOnTaps an element by text, id, or accessibility label.Waits for the element rather than failing immediately if it is not yet rendered.
inputTextTypes into the focused field.Usually preceded by a tapOn to set focus, exactly as a user would.
assertVisibleFails the flow unless the element is on screen.The only command that makes a flow a test rather than a script.
swipeScrolls or swipes in a direction.Needed far more often on mobile than its web equivalent, since content sits below the fold by default.
runFlowExecutes another flow file inline.The closest thing to a shared helper, and how login gets reused across flows.

Selector choice is where flows become durable or brittle. Matching by visible text is the fastest to write and breaks on the first copy change or the first localised build. Matching by view id survives both, and requires the application to expose meaningful identifiers, which is a development decision rather than a testing one. The trade is the same one covered in software testability: how easily a system can be automated is decided before any test is written.

Next-generation test execution with TestMu AI

Maestro vs Appium

Maestro testing and Appium both drive real mobile applications, and they suit different teams rather than ranking against each other.

QuestionMaestroAppium
A test isA YAML flow, interpreted.A program in Java, Python, JavaScript, or C#.
Setup before first testInstall the binary and write a file.Server, client library, driver, and a build.
WaitingImplicit in every command.Explicit waits you write and tune.
Loops and branchingLimited and awkward by design.Whatever the language supports.
ReuserunFlow to call another file.Functions, classes, and page objects.
Who can authorAnyone who can read the flow.Someone comfortable in the language.
Best fitFast smoke coverage of core journeys.Large suites with data setup and custom logic.

The honest summary is that Maestro is faster to start and hits a ceiling sooner. A team with no mobile automation at all gets more value from ten Maestro flows written this week than from an Appium framework that is still being designed. A team already running a mature Appium suite gains little by porting it. Both frameworks execute on the same infrastructure, so the choice does not have to be made once and forever.

Running on Real Devices

Locally, Maestro drives whatever is plugged in or emulated, which is one device configuration. Mobile defects concentrate in the gaps between device models, OS versions, and screen sizes, so a suite that only ever runs on one handset is testing the least interesting configuration you have.

Running the same flows on TestMu AI covers that spread across 10,000+ real devices without owning any of them. Maestro executes through HyperExecute, and the whole run is described by one configuration file. Upload the build first and keep the returned identifier:

curl -u "USERNAME:AccessKey" -X POST \
  "https://manual-api.lambdatest.com/app/upload/realDevice" \
  -F "appFile=@/path/to/your/app.apk" \
  -F "name=sampleApp"

# Response contains an APP_ID you reference as lt://APP1234...

Then describe the run. The configuration below is from a working Maestro setup on HyperExecute, with autosplit distributing the discovered flows across the requested devices:

version: "0.2"
autosplit: true
concurrency: 2
runson: android

runtime:
  - language: java
    version: "21"

framework:
  name: raw
  args:
    devices: [".*-.*", ".*-.*", ".*-.*"]
    video: true
    deviceLog: true
    appPath: maestro-test/sample.apk
    buildName: maestro-t1
    queueTimeout: 600

testDiscovery:
  command: cat ./maestro-test/discover.txt
  mode: static
  type: raw

testRunnerCommand: ./maestro-test/runTest_android_emulator.sh $test

report: true
partialReports:
  - location: .
    type: xml
    frameworkName: junit

The runner script is the part that actually invokes Maestro on the machine, and it is deliberately thin:

#!/bin/bash
adb devices
maestro -v
maestro test $1 --debug-output ./MaestroLogs --format junit

Then trigger the run. Each discovered flow is dispatched to a device, and the dashboard collects the results:

./hyperexecute --user USERNAME --key AccessKey --config hyperexecute.yaml

Both real devices and Android emulators are supported, and pre-installed system apps can be targeted by setting the app identifier to stock and naming the package in the flow. Full setup, including the iOS path, is in the HyperExecute Maestro documentation.

Reports and Debugging

The format flag in the runner above is doing more work than it looks. It makes Maestro emit JUnit XML, which is the interchange format every CI system and most test management tools already understand, so results land somewhere durable instead of scrolling past in a log.

Debugging a mobile failure needs more than a stack trace, because the interesting question is usually what was on screen. The debug output directory captures logs and screenshots locally. On a grid run, video and device logs attach to each execution, which is what turns a failure that only reproduces on one device model into something a developer without that handset can act on.

Feed the JUnit output into test management if you want history rather than a per-run verdict. A single failing flow is a defect; the same flow failing on one device family for three weeks is a different and more useful finding.

Where Maestro Struggles

Every account of Maestro testing should state these plainly, because the parts a framework is bad at decide whether it fits your suite more than the parts it is good at.

  • Conditional logic. Declarative YAML has no natural way to express take this path if the user has a saved card, and flows that need it become several near-duplicate files.
  • Data-driven runs. Testing twenty input combinations means twenty flows or an external generator, where a programming language would use a loop.
  • Test data setup. There is no way to call your own code to seed an account, so setup either happens through the UI, which is slow, or outside the framework entirely.
  • Cross-platform reuse. The commands are shared between Android and iOS but the selectors usually are not, so one flow rarely runs untouched on both.
  • Deep assertions. Checking that a value persisted correctly to a backend is outside what a UI-level flow can see, and stays the job of API-level checks.

None of these are defects. They are the cost of the trade that makes a first flow take minutes. The teams that get the most from Maestro use it for the journeys that must never break and keep a programmable framework for the suites that need logic, which is a division of labour rather than a migration.

Note

Note: Write the flow once and run it across real Android and iOS hardware rather than the one handset on your desk, with video and device logs attached to every execution. Start free

Conclusion

Pick the one journey whose breakage would be most embarrassing and write it as a flow this afternoon. Launch, navigate, assert one thing that proves the journey worked. If it takes longer than an hour, the obstacle is your app's selectors rather than the framework, and that is a finding worth having on its own.

Then decide the division of labour deliberately. Maestro for the flows that must never break and that non-engineers should be able to read; a programmable framework for suites that need loops, seeded data, and calls into your own code. Choosing one tool for everything is what forces the compromise.

Whichever mix you land on, run it on hardware your users actually hold. TestMu AI's real device cloud covers that spread, and the broader picture of what to test on mobile is in the mobile app testing guide.

Author

...

Bhawana

Blogs: 69

  • Twitter
  • Linkedin

Bhawana is a Community Evangelist at TestMu AI with over 3 years of experience creating technically accurate, strategy-driven content in software testing. She has authored 50+ blogs on test automation, cross-browser testing, mobile testing, and real device testing. She also serves as Product Marketing Manager for Kane CLI, the command-line tool that runs browser automation from the terminal using natural-language flows in a real Chrome browser. Bhawana is certified in KaneAI, Selenium, Appium, Playwright, and Cypress, reflecting her hands-on knowledge of modern automation practices. On LinkedIn, she is followed by 6000+ QA engineers, testers, AI automation testers, and tech leaders.

Open in ChatGPT Icon

Open in ChatGPT

Open in Claude Icon

Open in Claude

Open in Perplexity Icon

Open in Perplexity

Open in Grok Icon

Open in Grok

Open in Gemini AI Icon

Open in Gemini AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free
...
TestMu Conf 2026

World's largest virtual agentic engineering & quality conference

...

AUG 19-21, 2026

REGISTER NOW

Maestro Testing FAQs

Did you find this page helpful?

More Related Blogs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests