Using Object-Oriented Principles in Test Code

O'Reilly Media
oreillymedia
Published in
4 min readSep 22, 2020

Editor’s Note: Writing test code is an important (if annoying) part of developing software that is reliable and maintainable over the long term. In her piece from 97 Things Every Java Programmer Should Know, Java Champion and test automation expert Angie Jones shares why you should apply the same OO principles to test code as you would to production code.

When writing test code, it’s important to exercise the same care that you’d use when developing production code. Here are common ways to use object-oriented (OO) principles when implementing test code.

Encapsulation

The Page Object Model design pattern is commonly used in test automation. This pattern prescribes creating a class to interact with a page of the application under test. Within this class are the locator objects for the elements of the web page and the methods to interact with those elements.

It’s best to properly encapsulate by restricting access to the locators themselves and only exposing their corresponding methods:

public class SearchPage {
private WebDriver driver;
private By searchButton =
By.id(“searchButton”);
private By queryField = By.id(“query”);
public SearchPage(WebDriver driver){
this.driver = driver;
}
public void search(String query) {driver.findElement(queryField).sendKeys(query);
driver.findElement(searchButton).click();
}
}

Inheritance

While inheritance should not be abused, it can certainly be useful in test code. For example, given there are header and footer components that exist on every page, it’s redundant to create fields and methods for interacting with these components within every Page Object class. Instead, create a base Page class containing the common members that exist on every page, and have your Page Object classes inherit from this class. Your test code will now have access to anything in the header and footer no matter what Page Object they are currently interacting with.

Another good use case for inheritance within test code is when a given page has various implementations. For example, your app may contain a User Profile page that has different functionality based on roles (e.g., Administrator, Member). While there are differences, there could also be overlap. Duplicating code across two classes is not ideal. Instead, create a ProfilePage class that contains the common elements/interactions, and create subclasses (e.g., AdminProfilePage, MemberProfilePage) that implement the unique interactions and inherit the common ones.

Polymorphism

Assume we have a convenience method that goes to the User Profile page. This method doesn’t know what type of profile page it is — an Administrator or a Member.

You’re faced with a design decision here. Do you make two methods — one for each of the profile types? This seems like overkill since they both would do the exact same thing but just have a different return type.

Instead, return the superclass (ProfilePage) since both AdminProfilePage and MemberProfilePage are both subclasses of ProfilePage. The test method that is calling this convenience method has more context and can cast accordingly:

@Test
public void badge_exists_on_admin_profile() {
var adminProfile =
(AdminProfilePage)page.goToProfile("@admin");
...
}

Abstraction

Abstraction is used sparingly in test code, but there are valid use cases. Consider a type of widget that has been customized for different usages throughout the app. Creating an abstract class that specifies the behaviors expected is helpful when developing classes that interact with specific implementations of that widget:

public abstract class ListWidget {
protected abstract List<WebElement> getItems();
int getNumberOfItems() {
return getItems().size();
}
}public class ProductList extends ListWidget {
private By productLocator =
By.cssSelector(".product-item");
@Override
protected List<WebElement> getItems() {
return driver.findElements(productLocator);
}
}

Test code is indeed code, meaning that it has to be maintained, enhanced, and scaled. Therefore, it’s in your best interest to follow good programming practices when developing it — including the foundational OO principles.

Learn faster. Dig deeper. See farther.

Join the O’Reilly online learning platform. Get a free trial today and find answers on the fly, or master something new and useful.

Learn more

Angie Jones is a senior developer advocate who specializes in test automation strategies and techniques. She shares her wealth of knowledge by speaking and teaching at software conferences all over the world, writing tutorials and technical articles on angiejones.tech, and leading the online learning platform, Test Automation University. As a Master Inventor, Angie is known for her innovative and out-of-the-box thinking style, which has resulted in more than 25 patented inventions in the US and China. In her spare time, Angie volunteers with Black Girls Code to teach coding workshops to young girls in an effort to attract more women and minorities to tech.

--

--

O'Reilly Media
oreillymedia

O'Reilly Media spreads the knowledge of innovators through its books, video training, webcasts, events, and research.