Functional graphical user interface (GUI) test automation is hard. It is because the web is constantly evolving to create a better user experience. Moreover, the problem is exacerbated by bad information on the web about how to correctly write functional tests.
That’s why most QA automation engineers complain about the “flaky” nature of their tests. But to improve the reliability of your automated functional tests, you first need to accept that the only thing constant in software development is change.
Once you accept that change is inevitable, you can focus on removing possible sources of change from your automation to increase test stability. Go through this exercise, and you will arrive at the page object pattern that removes most of the issues that have been making your tests unstable.
What is the most common problem automation engineers complain about with respect to functional test automation of the web?
I created this poll to confirm my suspicion that the number-one problem that plagues the test automation community. The results should come as no surprise: Most people complain that functional test automation with the web is flaky.
Twenty-seven percent of respondents complained about flakiness and synchronization issues. Even scarier is the fact that 53% of the automation engineers surveyed can only execute between 1 and 50 functional tests per day, with a 95% accuracy rate. I bet these numbers are inflated, and that a majority of automation engineers actually can only execute between 1 and 10 functional tests with at 95% accuracy per day.
I’m confident in these numbers simply from experience. At my last three employers, prior to my arrival, the testing teams were able to execute 0, 15, and 10 automated functional tests per day, respectively. Sure, they had more functional tests than that. But I didn’t trust them any more than I trust the Russians on a public network at Starbucks.
Why QA Engineers Struggle with Test Automation Stability
So why do so many automation engineers struggle with stable test automation? The reason is actually pretty straight forward, although I personally struggled with this concept for years. Then one day, while reading Robert Martin’s Clean Code: A Handbook of Agile Software Craftsmanship, it hit me: My automated functional GUI tests were WET, as in I wrote everything twice. And, says Martin, “duplication is the primary enemy of a well-designed system,” so writing everything twice was simply feeding my poorly designed system to become a larger mess.
That’s why a practice like page objects is so effective at helping to improve the stability of your automated functional GUI tests. When implemented correctly, page objects help to resolve many problems that make for a poorly designed, automated functional test.
The Page Object Pattern
The idea behind the page object pattern is straightforward, but their use alone doesn’t make them a great idea. With page objects, you use a layer of abstraction between your automated functional tests and the web page to decrease sources of duplication. In other words, you create a single class for a single web page. Then you use this class in your automated functional test to interact with the web page in the same way you would with the web page manually.
Why Use the Page Object Pattern?
Page objects enforce good object-oriented design principles, such as “don’t repeat yourself” (DRY). A good implementation of a page object helps you to remove duplication and follow the DRY principle. Since you need to interact with a web page using a class, you should encapsulate all of the duplication into methods and properties. Methods help to reuse code. Properties, usually linked to elements on a page, help you to have a single place where a locator for that element can change.
Using page objects also allows for easy maintenance. Since your test code is now reusable and encapsulated within methods and classes, this makes maintenance easier. Therefore, if you are looking at a sample test like the one below (regarding this page), you can see that you can easily update any element identifiers or methods in a single place.
The Benefits of Using Page Object Pattern
The test and its steps can remain intact. But if you want to update the implementation of the GoTo() method for example, that lives in a single place, in a single class: the ComplicatedPage.
Therefore, if you have 250 of these functional tests, a single change inside of the GoTo()method will propagate this change through all of your tests.
This creates more robust code because your tests are easier to maintain. A single change no longer means updating 250 instances. Instead, the paradigm is now that a single update to your code will propagate that change through all the tests that interacted with that method or property.
This approach also creates more readable tests. It’s easy to understand what this automated functional test is doing. If you have a basic understanding of coding, you can read a test written using the page object pattern. Also, you can understand its purpose. And if you’re using the page object pattern correctly, your tests will read like live documentation. This renders the need for actual documentation useless. It is because your automated functional tests can tell you exactly how the application is supposed to behave.
Are You Really Using The Page Object Pattern?
Just the fact that you’re using page objects in your functional test automation doesn’t necessarily mean that your tests will be more robust. You need to implement the page objects correctly.
I am looking for an excellent Selenium Webdriver with Java instructor to teach students on my website. After asking for a specific code sample of one individual’s tests using page objects, this is what I received:
This makes me angry — not at the individual, but at the fact that this person was lead to believe that this is the right way to write an automated functional GUI test. This individual, who has nine years of development experience and six years of functional test automation experience under his belt, believes that this is a great test.
I have several problems with this example. First, I have zero understanding about what this functional test does. Second, this test has absolutely no reference to a single page class. Finally, based on my very shallow understanding, it seems as though all of the softValidate() methods are interacting with some kind of HTML property. So when something on the web page inevitably changes, this test, along with 100 others, will need to be updated.
This kind of abomination is all too common. I’ve seen this kind of code for many years, and I still see it today. Here is another example:
Your Need to Use Page Object Pattern
Can you please explain to me what this functional test does? There is a bunch of commented out code, there are a bunch of variables that have data that don’t even get used in the test, and there is a reporting class in our functional test? Ugh.
After I refactored it, this is what the test looks and reads like. Please let me know if this functional test doesn’t read better than what you see above?
So I implore you, as a true professional, as an employee getting paid to do a great job, to learn the proper way to write a functional test using a page object. There are many great ways to write a functional test using a page object. But the code example above is not one of them. I have an entire course that teaches you how to write functional tests with page objects. I won’t say that my method is the best in the world, as I am always making improvements and learning. But I can definitely say that the refactored version of the test is drastically more robust and easier to understand than the one I received above.
Now, Create Your Own Page Objects
Automated functional test automation with the web is definitely hard. But you can make your life much easier by focusing on the DRY principle. By attempting to remove duplication from your tests, you will naturally begin to create great tests.
You can skip the learning curve and jump straight into a good implementation. There are plenty of good examples on the web. When you start applying any of these examples, your functional test automation will see a drastic improvement in its robustness.
That’s my advice for using page object patterns, but I’m always looking for ways to improve. Do you have a useful tip to share that I missed? If so, please post your comments below.
If you would like to learn more, I have an entire video course dedicated to the Page Object Pattern.