Automation1 min read

Designing Test Frameworks That Survive Their Second Year

Most automation frameworks rot within a year. The fix isn't a better tool — it's treating the framework as production software with real architecture.

Most test automation frameworks start clean and end as a graveyard of flaky tests nobody trusts. The tool is rarely the problem. The problem is that the framework was written as a pile of scripts instead of as software.

The symptom vs. the cause

Teams usually blame the symptom — flakiness, slow runs, brittle locators — and reach for a new tool. A year later they’re back in the same place, because the underlying cause was structural, not technological.

The frameworks that survive share one trait: the test author never touches infrastructure code. Waiting, driver setup, configuration, and reporting live behind stable interfaces.

A layered structure

Think in three layers, each depending only on the one below it:

  1. Tests — express intent, nothing else.
  2. Domain / page objects — model the application.
  3. Core — driver lifecycle, waits, config, reporting.
// A test says WHAT, never HOW.
@Test
void userCanLogIn() {
    loginPage.open()
             .signInAs(standardUser);
    assertThat(dashboard.isVisible()).isTrue();
}

Notice there’s no WebDriver, no sleep, no locator in sight. That’s the point.

Waiting is a core concern, not a test concern

The single biggest source of flakiness is waiting logic copy-pasted into tests. Centralise it once:

public <T> T until(Function<WebDriver, T> condition) {
    return new WebDriverWait(driver, TIMEOUT).until(condition);
}

Now a locator change is one edit, and a timeout tuning is one edit — not fifty.

The test

Here’s the honest measure of a framework’s design: can a new engineer add a meaningful test on their first day without reading the core? If yes, it will survive its second year. If no, it won’t — regardless of the tool on the label.