Detecting Process Death issues with Maestro
After explaining what System-initiated Process Death is, showing how to detect it manually and automate detection with Appium, Iβd like to demonstrate how to automate detection this time with Maestro, a relatively new Automation tool! π
What is Maestro?
Maestro is a command line tool that allows us to run end-to-end UI tests, written in a simple YAML format.
Run the following command to install Maestro on Mac OS, Linux or Windows (WSL):
1
curl -Ls "https://get.maestro.mobile.dev" | bash
Using Maestro
Letβs go back to the demo project containing a fragment-based app built with two screens:
- A first screen to enter a name called EnterNameFragment
- Second one to show that information called ShowInfoFragment
- To pass a name value between those screens, a Singleton called DataHolder is used, which will lose its value after System-initiated Process Death.
A file called happy-flow.yaml
in a .maestro
folder will contain the following maestro commands:
1
2
3
4
5
6
7
8
9
10
11
12
13
appId: dev.galex.process.death.demo
---
- launchApp
- tapOn:
id: "dev.galex.process.death.demo:id/enter_name"
- inputText: "John Doe"
- tapOn:
id: "dev.galex.process.death.demo:id/next"
- assertVisible:
id: "dev.galex.process.death.demo:id/show_name"
text: "Name = John Doe"
enabled: true
- stopApp
Weβll run this test with the following command, from the demo project root folder:
1
maestro test .maestro/happy-flow.yaml
The result of running this test will show a successful run for our test:
1
2
3
4
5
6
7
8
9
10
11
12
Running on 41161FDJG002EG
β
β > Flow
β
β β
Launch app "dev.galex.process.death.demo"
β β
Tap on id: dev.galex.process.death.demo:id/enter_name
β β
Input text John Doe
β β
Tap on id: dev.galex.process.death.demo:id/next
β β
Assert that "Name = John Doe", id: dev.galex.process.death.demo:id/show_name is visible
β β
Stop dev.galex.process.death.demo
β
Triggering The Issue with Maestro
Since version 1.37.0
, which was finally released last week, Maestro offers the ability to trigger System-initiated Process Death using a command called killApp
which I was very happy to introduce into to the Maestro project. Yay to Open-Source! π
Weβll call this file appropriately detect-process-death-issue.yaml
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
appId: dev.galex.process.death.demo
---
- launchApp
- tapOn:
id: "dev.galex.process.death.demo:id/enter_name"
- inputText: "John Doe"
- tapOn:
id: "dev.galex.process.death.demo:id/next"
- assertVisible:
id: "dev.galex.process.death.demo:id/show_name"
text: "Name = John Doe"
enabled: true
- pressKey: Home
- killApp
- launchApp:
stopApp: false
- assertVisible:
id: "dev.galex.process.death.demo:id/show_name"
text: "Name = John Doe"
label: "Assert that \"Name = John Doe\" meaning the screen kept its data after System-initiated Process Death"
enabled: true
- stopApp
Letβs pay attention to the part that helps us reproduce the issue, with explanations in comments:
1
2
3
4
- pressKey: Home # Puts the app into the background
- killApp # Kills the app (adb shell am kill)
- launchApp: # Relaunches the app
stopApp: false # Without adb shell am stop
Weβll run this test with the following command:
1
maestro test .maestro/detect-process-death-issue.yaml
The result of running this test will fail:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Running on 41161FDJG002EG
β
β > Flow
β
β β
Launch app "dev.galex.process.death.demo"
β β
Tap on id: dev.galex.process.death.demo:id/enter_name
β β
Input text John Doe
β β
Tap on id: dev.galex.process.death.demo:id/next
β β
Assert that "Name = John Doe", id: dev.galex.process.death.demo:id/show_name is visible
β β
Press Home key
β β
Kill dev.galex.process.death.demo
β β
Launch app "dev.galex.process.death.demo" without stopping app
β β Assert that "Name = John Doe" meaning the screen kept its data after System-initiated Process Death
β π² Stop dev.galex.process.death.demo
β
Assertion is false: "Name = John Doe", id: dev.galex.process.death.demo:id/show_name is visible
==== Debug output (logs & screenshots) ====
/Users/galex/.maestro/tests/<date>
Perfect! Weβve successfully detected the System-initiated Process Death issue with Maestro! π
In the generated folder /Users/galex/.maestro/tests/<date>
weβll find the screenshots taken by Maestro, showing the ShowInfoFragment screen with the text Name = null
instead of Name = John Doe
:
Improving our Maestro Test
To be able to re-use the commands that allow us to trigger System-initiated Process Death, we can put them in another .yaml
file named trigger-process-death.yaml
:
1
2
3
4
5
6
appId: dev.galex.process.death.demo
---
- pressKey: Home # Puts the app into the background
- killApp # Kills the app (adb shell am kill)
- launchApp: # Relaunches the app
stopApp: false # Without adb shell am stop
And use the runFlow
command in our original detect-process-death-issue.yaml
test to include it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
appId: dev.galex.process.death.demo
---
- launchApp
- tapOn:
id: "dev.galex.process.death.demo:id/enter_name"
- inputText: "John Doe"
- tapOn:
id: "dev.galex.process.death.demo:id/next"
- assertVisible:
id: "dev.galex.process.death.demo:id/show_name"
text: "Name = John Doe"
enabled: true
- runFlow: trigger-process-death.yaml
- assertVisible:
id: "dev.galex.process.death.demo:id/show_name"
text: "Name = John Doe"
label: "Assert that \"Name = John Doe\" meaning the screen kept its data after System-initiated Process Death"
enabled: true
- stopApp
The output of running detect-process-death-issue.yaml
will look almost the same as before:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Running on 41161FDJG002EG
β
β > Flow
β
β β
Launch app "dev.galex.process.death.demo"
β β
Tap on id: dev.galex.process.death.demo:id/enter_name
β β
Input text John Doe
β β
Tap on id: dev.galex.process.death.demo:id/next
β β
Assert that "Name = John Doe", id: dev.galex.process.death.demo:id/show_name is visible
β β
Run trigger-process-death.yaml
β β Assert that "Name = John Doe" meaning the screen kept its data after System-initiated Process Death
β π² Stop dev.galex.process.death.demo
β
Assertion is false: "Name = John Doe", id: dev.galex.process.death.demo:id/show_name is visible
==== Debug output (logs & screenshots) ====
/Users/galex/.maestro/tests/<date>
Weβve improved the re-usability of our detecting method!
Conclusion
Weβve successfully detected the System-initiated Process Death issue with Maestro! πͺ It makes the whole ordeal so easy I seriously think an E2E Maestro test should be a part of every feature we build to ensure its quality and robustness! π
Let me know what you think or if you have any questions in the comments! π
Happy testing! π§ͺ