Come join our happy hour in Seattle! – Click here.

Lessons Learned on Automation Episode III: Modularity and Reusability Matters

Contents

In my previous blog posts, we worked on achieving throughput via parallelism and making each test as reliable as possible.

The next missing piece in the puzzle is related to modularity and reusability. We are living in a world of Continuous Integration and Continuous Delivery, so we want our framework to be extended easily and quickly adapt to changes in the application being tested.

That leads us to our next lesson:

Follow the Page Object Model

This topic has been extensively discussed in the Selenium world, but as a brief summary, Page Object Design Pattern helps when modeling your application. Each “page” of your application (whether it is a Web App or Mobile App) is encapsulated into one class, and all the possible interactions on that application component are implemented there.

When done right, these objects can be reused across all your test suites. With that high level of abstraction, you can adapt your tests to changes on your underlying application with little effort.

As an example, let’s work on Wikipedia. A test that searches for a topic and goes to that page might look like:

@Test
public void testWikipedia() {
    driver().get("https://www.wikipedia.org/");
    Thread.sleep(3000);
    
    driver().findElement(By.id("searchInput")).sendKeys("WebDriver");
    Thread.sleep(3000);
    
    driver().findElements(By.className("suggestion-link")).get(0).click();
    Thread.sleep(3000);
    
    String title = driver().findElement(By.id("firstHeading")).getText();
    Assert.assertEquals("Selenium (software)", title);
}
Java

In the example above, the test first browses to Wikipedia, then searches for “WebDriver”, goes to the first result and finally asserts that the title of the landing page is “Selenium (software)”.

In this scenario, besides the poorly managed timing criteria used (check out this blog post on how to deal with it), we are facing another painful problem:

There is no separation between the test and the application being tested.

As a result, when extending our coverage, we start duplicating code in the different tests. If at one point, for example, the locator of the search button changes, we have to go through all the tests using that functionality to apply the new locator. This approach quickly becomes unmanageable.

In the AugmentedDriver world, we can define Page Objects:

public class MainPage extends WebPageObject {
    @Override
    public Optional < By > visibleBy() {
        return Optional.of(Bys.INPUT);
    }

    public void search(String search) {
        driver()
            .augmented()
            .findElementClickable(Bys.INPUT)
            .sendKeys(search);
    }

    public WikiPage selectSuggestion(int index) {
        driver()
            .augmented()
            .findElementsVisible(Bys.SUGGESTION)
            .get(index)
            .click();
        return get(WikiPage.class);
    }

    public static class Bys {
        public static final By INPUT = By.id("searchInput");
        public static final By SUGGESTION = By.className("suggestion-link");
    }
}

public class WikiPage extends WebPageObject {
    @Override
    public Optional < By > visibleBy() {
        return Optional.of(Bys.TITLE);
    }

    public String getName() {
        return driver().augmented().findElementVisible(Bys.TITLE).getText();
    }

    public static class Bys {
        public static final By TITLE = By.id("firstHeading");
    }
}
Java
Expand

And now our test looks like:

@Test
public void testWikiPedia() {
    WikiPage wikiPage = mainPage()
        .search("WebDriver")
        .selectSuggestion(0);

    Assert.assertEquals("Selenium (software)", wikiPage.getName());
}

private MainPage mainPage() {
    driver().get("https://www.wikipedia.org/");
    return get(MainPage.class);
}
Java

The only requirement of a WebPageObject is that you need to implement the method visibleBy(). The framework won’t instantiate the object until that By is visible. This helps significantly with reliability since the AugmentedDriver will wait until the application is in the right state before the test can continue.

With this approach, there is a clear separation of the test and the business logic of your application. Locators are defined once inside the Page Object Class, greatly reducing the effort of adapting the tests to changes. New functionality can also be added inside the Page Object Class and immediately reused on any other test, reducing code duplication and accelerating the development of new tests.

In summary, as part of a Continuous Integration ecosystem, your UI Automation Tests should be able to adapt quickly to changes. By following the Page Object Model, tests and business logic are pulled apart from each other; Easing up not only on the maintainability effort but also reducing the time spent on covering new functionality.

Get Split Certified

Split Arcade includes product explainer videos, clickable product tutorials, manipulatable code examples, and interactive challenges.

Switch It On With Split

The Split Feature Data Platform™ gives you the confidence to move fast without breaking things. Set up feature flags and safely deploy to production, controlling who sees which features and when. Connect every flag to contextual data, so you can know if your features are making things better or worse and act without hesitation. Effortlessly conduct feature experiments like A/B tests without slowing down. Whether you’re looking to increase your releases, to decrease your MTTR, or to ignite your dev team without burning them out–Split is both a feature management platform and partnership to revolutionize the way the work gets done. Switch on a free account today, schedule a demo, or contact us for further questions.

Want to Dive Deeper?

We have a lot to explore that can help you understand feature flags. Learn more about benefits, use cases, and real world applications that you can try.

Create Impact With Everything You Build

We’re excited to accompany you on your journey as you build faster, release safer, and launch impactful products.