Using Page Object Pattern in Automation Testing
Writing automated tests for quick bugs finding during early phases of software development cycles is a must. Test automation allows to reduce bugs fixing costs and improve overall quality assurance process. However, writing automating tests isn't as simple as it seems it possibly may end up with poorly applied tests and increased costs of code maintenance.
In this article I would like to share the experience of applying Page Object pattern in Appium + Java combination for native Android applications automation. We tend to use this pattern, since it allows us to write maintainable and reusable test routines, which are easy to read and understand.
The problem of simple tests recorded by Record Playback
In my experience, if the recorded appium tests are used more than once, over time such tests are accumulated. They quickly turn into a big heap of rubbish which is difficult to maintain, and furthermore to gain a positive result for the project.
Let's say we have 20 tests and we use a link to the sidebar button in each test.
If you change your application UI, you will need to change the value of the locator respectively in all 20 tests manually. That in turn leads to the necessity to spend a lot of time fixing each test. No wonder we decided to abandon this option in favor of Page Objects pattern.
What is Page Objects
Simply put, the Page Objects is an application screens simulation in the form of objects that interact with each other. The main goal is power-sharing, namely, the entire "business logic" should be placed in the Page Objects, while test classes only call public methods and check the results.
Advantages of using Page Object:
- improved tests readability
- ability to reuse the code
- simplicity to maintain tests when changing UI
- logic splitting
What Page Object includes
Let's deep into details what Page Object consists of. Having a native application, for example, with the authorization, registration and Main screen. You launch the application and get to the authorization screen this is our page. Next everything you can do on this screen (for example, to carry out the registration) is the action, and of course everything you see on this screen (inputs for data input and buttons) is, in fact, elements which Page Object operates itself.
Bearing this in mind we infer that the Page Object has the following entities:
- class (which implements the screen itself)
- attributes (all elements on the screen)
- methods (working with a screen and performing actions)
Having figured out the basic concepts, let's proceed to the steps of writing tests:
- Script understanding is the most important part. You have to understand the script and browse through it several times.
- Pages splitting. When you run the script you should know pages and objects should be used.
- Tests design. You should understand the test itself and how it will look in whole with all verifications, switches to different screens and methods that will be in the test.
- The implementation of the code. It's a simple step as we have already formed everything we need in the test design. Now we just have to create all the classes and methods we are about to use.
- Code debugging. Towards the end you need to make sure that everything is working properly and we get the result that was claimed in the test script.
Here is a small example of the user authentication and how I use the page object pattern. I will skip all pre-launch preparation tests and show just how I implement the actual test.
We start with the definition of the case. In this case it is the user authorization. The first thing we do is browsing through the script in the application. We see that we have two screens: the first the authorization screen, the second the main screen after authorization.
Let's have a look at the authorization screen. It consists of two inputs for email address and password entering, and two buttons: for authorization (Sign In) and go to the registration screen (Register now).
We are writing test in a way how we see it.
In the test we write only those steps that we want to see and verifications that we want to use. The entire implementation will be thrust into the class called LoginPage. Next in the created class we have to initialize all locators, which will be used, and to write one method to authenticate the user. In this example, we see that if we change the value of the locator, we do not need to spend a lot of time fixing it, one has only to enter the LoginPage class and fix the locator value. Previously written test will not be harmed.
What Page Object gives us
If in the first test we have already written the code for user authorization, and in the second test we want to add authorization under a different user and further moving through the application, we will not have to describe all elements and methods of the screen from scratch. We just take and reuse already written tests. This is the big advantage of using this pattern.