Maestro: Making UI Testing Automation for React Native and Flutter Painless

Development tutorial - IT technology blog
Development tutorial - IT technology blog

The “Broken Flow” Nightmare Right Before Release

Friday afternoon, just as the team is getting ready to head out for drinks, a bug appears. The scenario is all too familiar: You’ve just merged a new feature and feel confident it works. However, it accidentally breaks the Sign-up flow that had been running smoothly for the past 3 months.

I once participated in refactoring a codebase of over 50,000 lines for a Fintech project. The hard-earned lesson was: Never rely entirely on manual testing. Modifying even a single line of code without the protection of a UI Test suite is like gambling with your luck. However, writing UI Tests for mobile has traditionally been an exhausting experience.

Why is Mobile UI Testing So Difficult?

If you’ve ever touched Appium, you surely know the feeling of spending all day just configuring the environment, WebDriver, and struggling with a mess of complicated dependencies.

UI Testing is often overlooked in small and medium projects due to three major barriers:

  • Overly complex setup: You have to install everything from Node.js and Appium Server to specific drivers.
  • Slow and unstable (Flakiness): Tests often fail for no reason due to emulator latency or app animations. A suite of 20 cases might fail 5 just because the virtual machine… lagged.
  • Requires a specific language: You just want simple UI testing but end up having to learn a bulky framework in Java or Python.

Common Solutions Today

Before diving into Maestro, let’s look at some familiar names in the market:

  1. Appium: Extremely powerful, but maintenance is a nightmare for Juniors.
  2. Detox (React Native): Fast because it hooks deep into the code. However, initial configuration for Android is extremely time-consuming.
  3. Flutter Integration Test: Great for Flutter, but not the optimal choice if your project is cross-platform or needs a unified tool.

Maestro: Simplifying Every Process

Maestro completely changes this approach. Instead of writing complex script code, you define test steps using YAML files. It works seamlessly with React Native, Flutter, Native iOS, and Android.

The biggest plus of Maestro is its ability to handle animations and latency. It automatically waits for elements to appear, reducing the “flaky test” rate to a minimum.

Step 1: Install Maestro in 30 Seconds

On macOS or Linux, you only need to run a single command:

curl -Ls "https://get.maestro.mobile.dev" | bash

Then, restart your terminal and check the version to ensure a successful installation:

maestro --version

Note: On Windows, you should use WSL2 for the best experience.

Step 2: Assign Identifiers to UI Elements

For Maestro to find UI components on the screen, we need to assign IDs to them.

  • For React Native: Use the testID attribute.
<TouchableOpacity testID="login_button" onPress={handleLogin}>
  <Text>Login</Text>
</TouchableOpacity>
  • For Flutter: Use Semantics or Tooltip. Maestro also supports searching directly by the text content displayed on the screen.

Step 3: Write Your First Test Flow

Create a login_flow.yaml file. Let’s assume we need to test a basic login flow:

appId: com.example.myapp # Bundle ID (iOS) or Package Name (Android)
---
- launchApp
- tapOn: "Email"
- inputText: "[email protected]"
- tapOn: "Password"
- inputText: "123456"
- tapOn: "login_button"
- assertVisible: "Welcome!"

This structure is extremely easy to understand. Even Manual QAs can participate in writing and understanding the test suite without deep coding knowledge.

Step 4: Execute and Observe Results

Open the Emulator or Simulator with the app installed, then run the command:

maestro test login_flow.yaml

Maestro will automatically perform the tap, input, and assertion actions. If you want the test to automatically rerun whenever you save the file (similar to Hot Reload), add the -c flag:

maestro test -c login_flow.yaml

Pro Tip: Use Maestro Studio

This is the ultimate time-saving feature. Instead of guessing the element names, just type:

maestro studio

A web interface will appear. Simply hover over any component on the virtual device’s screen, and Maestro will immediately suggest the corresponding YAML command. You just need to copy and paste it into your test file.

Integrate CI/CD to Protect Your Source Code

Once the flows are running stably on your local machine, I usually integrate them into GitHub Actions. Every time there’s a new Pull Request, the system automatically runs the entire test suite.

This prevents accidentally breaking existing features. Note that when running on CI, you need to configure a virtual machine environment (like a macOS runner for iOS) so Maestro can execute.

Don’t wait until your application encounters critical errors in Production to start writing tests. Start with the most important flows like Login or Checkout using Maestro today. Its simplicity will make you regret not using it sooner!

Share: