The Page Object Pattern is a programming style for testing purposes, in which the functionality of a UI-component is being wrapped by an accessor class. Doing this allows us to access UI-components in an easy manner. The Page Object Pattern is being explained for Webpages by Martin Fowler in a blog post he has written some time ago. As he explains you can wrap functions of a webpage in a class and offers methods to mimic the typical user input on the webpage. (http://martinfowler.com/bliki/PageObject.html)
This Blog Post will explain, how to leverage this concept in Android Espresso Tests and take advantage of the simplified process of writing testcases suiting your needs.
Page Object Pattern
Martin Fowler states in his Blog Post, that every functional unit of the displayed page should be wrapped by a so called Page Object. The Page Object allows you to interact with the UI as if you were sitting in front of the screen and offers reusability of the written code.
Let us transport this pattern over to the mobile world. The mock below shows a simple UI that offers three fragments. The first two fragments are being hosted in a tab-view, so you can switch between the two by clicking the tab. Also there is a bunch of input fields in each of the two fragments. Furthermore a button is located in the second fragment, that allows the user to navigate to a third fragment, that displays an image. Here is how you can map this example to the Page Object Pattern:
From mock to class
Create a Page Object class for each of the three fragments.
Verify the initial page layout in the constructor of the class.
Each class offers methods according to the possible user interactions like:
enter text in input fields
switch to tab1 or tab2
click the button
click the hardware back button
Each method may implement input assertions, assertions on UI layout or behaviour, according to the use case.
When a UI interaction requires you to navigate to another fragment, the according Page Object must be returned by that method
By implementing the pages in this way, you can easily setup testcases, that display a certain workflow. The verification of a user-interaction doesn’t have to be rewritten each time, because the Page Object itself implements the required assertions for the test.
The Show-Case App I am going to use is the Android App Scrum Poker. Currently I am using the Page Object Pattern with the Android Espresso Tests in my build scenario. The following example implementation demonstrates on how to use the Page Object Pattern.
Get an impression of the UI-elements to test.
Create a Page Object per screen.
Define a Espresso-Test Class as Orchestrator.
Overview of the screens to test
At first I will show you an outline of the implemented screens. The sample App defines two Activities. The first Activity contains a Fragment that displays the available Scrum Poker Cards, called CardsFragment, and a second Fragment that displays a Countdown-Timer, called TimerFragment. The second Activity is being used to set the Countdown-Timer, called CustomTimePickerActivity. In my Test-Workflow I am going to navigate from the CardsFragment to the TimerFragment and perform a click on the Countdown-Timer, in order to open the CustomTimepickerActivity. The following demonstrates the example Workflow I am going to test:
Example screen flow
Overview of the Test-Classes to implement
As you can see here, there are three Page Objects and one test class to be implemented.
The class EspressoUITest is the test class and simulates the user interactions.
The class TestCardsFragment wraps the functionality of the CardsFragment
The class TestTimerFragment wraps the functionality of the TimerFragment
The class TestCustomTimePickerActivity wraps the functionality of the CustomTimePickerActivity
The class EspressoUITest serves as orchestrator, as stated before. If you don’t know on how to setup an Espresso Test class have a look at my previous Blogpost, that explains how to use Espresso Tests. In this post I’m only showing the basic interaction with the Page Objects.
As shown in the codeblocks, you will have to create a test method for your test workflow. When you are using the Page Object Pattern you can reuse each interaction with the UI and don’t have to write the assertions, because they are actually located in the Page Object.
The test statement can be simplified even further using the fluent api, that is provided using the Page Object Pattern as shown above.
By using the Page Object Pattern it is easy to write a test that is easy to understand. The reusability of the Page Objects is high and you can save a lot of work by using them. The maintenance work is also reduced, because it is simple to identify the methods that need to be adjusted.