End‐To‐End Testing with Maestro - Swent-Fall-2024-team-10/leazy GitHub Wiki
End-to-end (E2E) testing allows you to simulate real-world user interactions with your app, ensuring that key workflows function as expected. Maestro is a tool specifically designed to automate E2E testing in a simple and effective way, particularly for React Native apps.
Cross-Platform: Maestro supports both iOS and Android. Simple YAML-based Syntax: Define flows easily in YAML format. Test Automation: Automate complex workflows like login, navigation, and form submissions. Fast Feedback Loop: Run tests locally and see results in real-time.
To install Maestro, run the following commands:
Run the following command to install Maestro on macOS, Linux or Windows (WSL):
curl -fsSL "https://get.maestro.mobile.dev" | bash
Dependencies:
Xcode (recommended version is 14 or higher)
Please make sure that Command Line Tools are installed (Xcode -> Preferences -> Locations -> Command Line Tools)
After setting up the macOS dependencies above, follow the default installation instructions:
brew tap mobile-dev-inc/tap
brew install maestro
After installation, check if Maestro is installed correctly by running:
$ maestro -v
Ensure that your app is set up with correct app identifiers to be compatible with Maestro:
For iOS: Add ios.bundleIdentifier
in app.json
.
For Android: Add android.package
in app.json
.
Example app.json:
{
"expo": {
"name": "leazy",
"slug": "leazy",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "myapp",
"userInterfaceStyle": "automatic",
"splash": {
"image": "./assets/images/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.swent.leazy"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.swent.leazy"
},
"web": {
"bundler": "metro",
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"experiments": {
"typedRoutes": true
}
}
}
Ensure that you have the bundle identifier and package defined as Maestro uses them to launch the app for testing.
You can write Maestro flows in a YAML file that defines each step of the user interaction. (create a flow.yml file in the root of the project)
Example Workflow: Testing Navigation and Form Submission In this example, we'll test a navigation flow where the user:
1 . Opens the app. 2. Navigates to "Settings." 3. Goes back. 4. Taps on "Report." 5. Submits a form with issue details.
Test flow file (flow.yaml):
appId: "com.swent.leazy"
---
- launchApp
- tapOn: "Go to Settings"
- tapOn :
id: "go-back-button"
- tapOn:
point: "7%,6%"
- tapOn: "Report"
- tapOn: "Name the issue"
- inputText: "Meastro test for e2e"
- tapOn: "Description"
- inputText: "This is a test for e2e"
You can run your Maestro test locally using the following command on a new tab:
$ maestro test flow.yaml
After starting the app by doing this command :
npx expo start
To make your flows less dependent on UI text and more flexible across different languages or environments, you can use test IDs for selecting UI elements.
<TouchableOpacity testID='go-back-button' style={styles.backButton} onPress={() => navigation.goBack()}>
<Ionicons name="arrow-back" size={24} color="black" />
<Text style={styles.backButtonText}>Back</Text>
</TouchableOpacity>
<Button title="Sign in" testID="signInButton" onPress={handleSignIn} />
Then, in your Maestro flow:
- tapOn:
id: "signInButton"
Or you can use directly the title of the button :
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')} // Navigate to Settings
/>
Also if you are stuck on how to interact with button that do not exist on the code (I had this problem where I couldn't find the navigation button), you can use the command $ maestro studio
after launching your simulator.
It will allow you to visually select UI elements in order to receive suggestions on how to interact with the element in your Flow
Maestro Studio automatically generates examples of how you can interact with the selected element in your Flows. You can double click on the example to execute it directly, or use the hotkeys to copy it to the clipboard or open the relevant documentation
Maestro can generate random text, emails, and numbers, which is useful for testing forms:
- inputRandomText
- inputRandomEmail
- inputRandomNumber
Use assertions to check if elements are visible or if certain conditions are met. For example, verifying if a success message appears:
- assertVisible: "Sign in successfully"
You can reuse common steps (like logging in) by creating nested flows:
# sign-in-subflow.yaml
appId: com.example.app
---
# Enter username
- tapOn:
id: "usernameInput"
- inputText: ${USERNAME}
- hideKeyboard
# Enter password
- tapOn:
id: "passwordInput"
- inputText: ${PASSWORD}
- hideKeyboard
# Main flow using the nested flow
- runFlow:
file: sign-in-subflow.yaml
env:
USERNAME: "TestUser"
PASSWORD: "TestPassword"
You can record a video of the flow execution to review or debug later:
$ maestro record flow.yaml
This generates an .mp4 video that shows the entire flow being executed, which is useful for debugging complex interactions.
Maestro provides a flexible and powerful way to write end-to-end tests for React Native applications. With the YAML-based syntax, you can easily automate workflows and ensure your app behaves correctly in various scenarios. You can also integrate your tests into your CI pipeline and use advanced features like random input generation and recording flows for debugging.
Make sure to use test IDs for more reliable testing and take advantage of nested flows to reduce code duplication in your tests.
I will do a demo for you on Thursday so that you'll be able to visualise everything