Reader small image

You're reading from  How to Test a Time Machine

Product typeBook
Published inMar 2023
Reading LevelN/a
PublisherPackt
ISBN-139781801817028
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Noemí Ferrera
Noemí Ferrera
author image
Noemí Ferrera

Noemí Ferrera is a self-taught programmer and wrote her first comprehensive program at the age of nine. When she grew up, she proceeded to achieve a degree in computer science specializing in hardware in Spain, a bachelor's degree in software engineering in Ireland, and a master's degree in computer science in Spain. She is an international speaker and participates in testing community conferences (such as Selenium, Appium, and Automation guilds) and engages with the community through Slack channels, Twitter, and her blog. In the 2020 Test Guilds publication, she was named as one of the top 28 test engineers to follow, as well as one of the top 33 test automation leaders to follow in the 2019 Tech Beacon and as one of the 100 women in tech to follow and learn from by agiletestindays in 2023.
Read more about Noemí Ferrera

Right arrow

Testing Automation Patterns

In the last three chapters, we explored the concept of the test pyramid in a deeper and unique way.
If you are skipping those chapters and reading this one directly, we recommend you go over the previous one for a better understanding of UI testing.

Most developers are familiar with development design patterns. In testing, we also have patterns, best practices, and ways of dealing with automation writing that have proven useful and can be re-used systematically. The most well-known of these patterns is the POM. In this chapter, we are going to cover some versions of it that have been useful in my career, and I hope they help you achieve reliable, maintainable, and faster automation code.

In this chapter, we are going to cover the following main topics:

  • The Page Object Model (POM) for UI automation
  • A Page Factory Model (PFM) – an antipattern?
  • A file objects model (FOM)
  • An enhanced POM (EPOM)
  • A remote POM (RPOM)
  • ...

Technical requirements

Some degree of programming skills is recommended to get the best out of this chapter.

Quality experts (SDETs/QA) might be interested in this chapter, as well as developers in a company that has shifted left that want to leverage their skills with end-to-end testing.

This chapter uses examples written in various programming languages. We recommend reviewing and working with different languages as a self-growth exercise; we will provide the implementation for other languages in our GitHub.

Some of these examples are hypothetical, as sometimes it is difficult to find the right kind of system where these sorts of automation would be used (and that can be shared with the readers), but we hope you can find a way to fit these examples to your problem.

Note

In this chapter, we will make references to DOM, according to the w3org

The Document Object Model (DOM) is an application programming interface (API) for valid HTML and well-formed XML documents...

The POM for UI automation

The POM is one of the best-known design patterns for writing test frameworks. It consists of separating the model (or test logic) from the pages (the declaration of objects and the locators of elements that those tests interact with). This allows the developer of the test code to find those objects and locators in an effortless way, rather than having to search all the instances of such objects across all the lines of code. The longest the test code, the more tedious this task becomes.

This model creates scalable and maintainable programs that can easily be changed if needed. While this is a good practice for any type of code (and could be considered part of the don’t repeat yourself (DRY) principle), it is especially critical for frontend test code, as the definition of locators and elements tends to change frequently.

Note

DRY’s goal is to reduce the redundancy and repetition of software patterns, replacing them with abstraction or...

A PFM – an antipattern?

In a PFM, the initialization of all the objects is done in a method called initElements, where the driver that controls the objects is passed as a parameter and the page gets initialized. The benefit of this is that the code for the pages is easier, as we only need the definition of the elements and/or locators (@FindBy) and not any repetitive code for finding those elements (driver.findElement(webElement)), which will be replaced by the use of the webElement object directly.

The page class in this case looks like this:

PageClass.java

package package com.packtpub.PFM;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class PageClass {
    @FindBy(id=" __BVID__336")
    WebElement searchElement;
    public PageClass(WebDriver driver) {
   ...

Exploring a FOM

In page object model, we could include small methods within pages (such as getters, clicks, and text setters – we could call that method object model). Then we can separate the objects into another document that can be edited without compilation. For example, they could be part of an XML, a CSV, or a JSON file.

The advantage of putting the objects into a separate method that is not part of compilation is obvious: being able to change the elements more quickly and at any time. However, keep in mind that testing over the new objects should be done prior to the production stage to make sure everything works as expected.

Getters and clicks methods could be as short as one line. However, sometimes, these methods can become more complicated than expected and it is interesting to separate them from the test logic. There is also the added benefit that this way, the objects are kept abstracted and encapsulated from the test logic, protecting them from unwanted editions...

EPOM

One of the reasons that record/playback tools are not popular is that they usually produce tests that are hard to maintain and therefore hard to escalate. In the previous sections, we have showcased the benefits of keeping the code in separate sections and ideally, we would like these tools to do so for us. However, even if the tools were to produce code in such a way, having screenshots and different object locators would revert the system to not being scalable.

We can enhance a POM to include screenshots and create automation that runs over the record/playback tools to create maintainable and scalable code, reducing the effort of writing repetitive lines. This will also work for other types of application-related elements:

Figure 5.5: Example of design of EPOM

Figure 5.5: Example of design of EPOM

For the following code example, we are going to use Python. The reason for this is that we will be using a library that allows you to find objects using a screenshot (the Airtest project...

RPOM

When the system needs to communicate with two different devices, we need some sort of way of controlling when each of them executes. In this case, we can use an RPOM design such as the following:

Figure 5.9: Example of an RPOM design

Figure 5.9: Example of an RPOM design

Here, we can have a test agent perform tests as if they were isolated, keeping the logic within them but the decision of the role the agent will play in the test is kept within the model. This is very useful when testing devices that cannot be handled remotely and need a test agent to be installed in them. This is the case for Windows applications, and there is good documentation about agents within Visual Studio’s docs: https://docs.microsoft.com/en-us/visualstudio/test/lab-management/install-configure-test-agents?view=vs-2022.

Let us see an example of a test agent and a model. The pages are omitted here, as the idea for them is the same as before. The example showcases how to handle a chat within an application...

Putting it all together

By now, you should be able to tell which one of the models is best for you. However, keep in mind that all of them (besides the PFM, which we consider an antipattern) are combinable.

Here is how it would look if all the models were working together:

Figure 5.10: Example of models working together

Figure 5.10: Example of models working together

With this, we could have multiple IDs for an object, including screenshots with different resolutions, and the pages would be handled by different agents, which could be called in different servers by the model. This would create powerful, maintainable, and scalable automation.

Whilst having all these models together might not be the right solution for all applications, we have displayed here that we have the flexibility of combining them to best fit our needs. In the next section, we will cover how to automate code repetition in these models so that we can have maintainable, well-designed code that is not tedious to write.

Automating the automation – a practical example

The general recommendation for test code writing is to make the tests short and simple. This way, we can identify the failing parts easily and clearly. However, sometimes, the time spent creating these simple tests surpasses that of the time of testing the parts that are likely to fail. The key is to find balance and try to reduce the time spent writing repetitive and predictable code.

We have seen before a few examples in which writing automation becomes a tedious and repetitive task: having to type the finders, create methods per object with repetitive header code, and tweak slight changes between them. We also mentioned that if we want the finders to fall through different locators (which will make the tests more robust in case those locators are lost), we will require repetitive code to do this.

Let us break down the process of automation again (as we did in Automating the automation section of Chapter 1, Introduction...

Dealing with dynamic object IDs

Although having a good development design with testability in mind is the ideal scenario (and we hope this book helps developers achieve it), the reality is not always as ideal. Sometimes, we inherit old code that has been built as a quick proof of concept or by someone that did not really care for testing so much. In this section, we will see some examples of that and what can we do to automate as much as possible around this. One example is the localized locators that we discussed earlier.

Items with dynamic locators

Sometimes, it is useful for an application to generate objects automatically. This happens quite frequently in games, where you can find sprites being generated as particles, bullets, or enemies. These may have an auto-generated ID (or another locator).

If that is the case, we should try looking for the object type, using a CSS locator for a particular class or similar.

Here’s an example of finding elements using a CSS...

Summary

In this chapter, we covered several models for UI automation test code writing, which can help create better-designed frameworks. We also reviewed some ways of automating the repetitive parts of the test code to help you achieve more with less effort.

We have visited different models that could help you differently: with remote topologies, with files with objects, and even with screenshots that can help you with visual automation.

Do you really need all of these testing patterns to write good and stable automation? Well, do you need wardrobes and drawers to be able to find things in your house? The answer is the same.

In the next chapter, we will go back to a lower part of the test pyramid and find out about models that can help us create better testing in CI/CD.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
How to Test a Time Machine
Published in: Mar 2023Publisher: PacktISBN-13: 9781801817028
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Noemí Ferrera

Noemí Ferrera is a self-taught programmer and wrote her first comprehensive program at the age of nine. When she grew up, she proceeded to achieve a degree in computer science specializing in hardware in Spain, a bachelor's degree in software engineering in Ireland, and a master's degree in computer science in Spain. She is an international speaker and participates in testing community conferences (such as Selenium, Appium, and Automation guilds) and engages with the community through Slack channels, Twitter, and her blog. In the 2020 Test Guilds publication, she was named as one of the top 28 test engineers to follow, as well as one of the top 33 test automation leaders to follow in the 2019 Tech Beacon and as one of the 100 women in tech to follow and learn from by agiletestindays in 2023.
Read more about Noemí Ferrera