"I'm looking over your shoulder... only because I've got your back." ~ Stephen Colbert
After my recent UiAutomator review a user brought up an important question about the use of UiWatcher. The watchers serve as async guardians of the test flow, making sure the odd dialog window doesn't completely frustrate your tests. Having a tool that automatically watches your back when you're focused on the functional flow of your tests is awesome. 100% pure awesomesauce. Since the API documentation on watchers is scant and the UI Testing tutorial on the Android dev guide doesn't cover their use in depth, I figured I should add a post here that goes over a simple scenario demonstrating how to use this fundamentally important UI automation tool.
In my example code below, I'm using uiautomator to launch the API Demo app (meaning run this against an Emulator built in API level 17 - I used the Galaxy Nexus image included in the latest ADT and platform tools). The test clicks down to the Alert Dialogs demo and automatically handles one of the dialogs popping up. It isn't a very legit test scenario but admittedly that's less the point than simply demonstrating the application of UiWatchers.
If I were testing the dialog itself, this could be a simple specification in BDD style:
- Given the API Demo app on an emulator at API level 17
- When I click on the first two OK Cancel dialog demo buttons
- It Should display an OK Cancel dialog
However, if I were testing some other function in the UI and there were a random chance of the dialog to appear, I wouldn't assert the dialog in my test flow because it could happen at any time. UiWatchers function by registering undesired but potential conditions and the uiautomator runner checks the registered watchers with its checkForCondition() method. This happens whenever you create UiObjects or UiCollections or update or evaluate them. This means that anytime you're trying to capture the UI and create/update/evaluate elements of the UI, the UiWatchers will have your back if something in your flow goes sideways.
Your watchers are managed by the UiDevice class The typical logic flow for implementing watchers follows this pattern:
- Define new watcher
- Register your watcher
- Run your watcher
The UiDevice class allows for much more watcher management than those three steps but those are the minimum necessary to get you there.
So on to the demo.
I've tried to be verbose in my comments to help walk you through what I'm doing but if you want to see it yourself, simply follow the setup steps in the UI Testing demo on the dev guide and paste this code in (adjusting as needed to adapt it to your environment). Secondly you'll need to launch an emulator set up with API level 17 to get the full chewy goodness of the latest accessibility and uiautomator APIs. Finally, you should follow the build and deploy steps in the dev guide and run it. If you want extra insight into how the UiWatcher is being called, add logging at line 67 just before creating the okCancelDialog UiObject. This will show you how often the runner is checking conditions with this watcher. It is pretty fascinating (and reassuring).