What would be the disadvantages of extending BaseTest from BasePage?

I’ve been working on abstracting and encapsulating most of the functionality of my automation project (that’s done in Java, using Selenium and Appium), so that there’s as little friction as possible when writing tests.

One of the decisions made was to implement my custom element interactions methods inside BasePage object (which were previously inside their own class called ExtendedDriver,java), so instead of having to write the usual:

We just call:

Another controversial decision was to then extend BaseTest from BasePage.
Again, this reduces the code we need to write, by not having to instantiate a page object to call our methods to interact with elements. This is particularly useful in Assertions and Verification, where we need to assert or verify something very specific to that Test, and doesn’t make much sense to implement that functionality in the corresponding PageObject, if it’s only going to be used once.
And so, instead of having something like:
assertThat(new LoginPage().getCurrentUrl().contains("login_challenge"), "Wrong url found.");

we can simply write:
assertThat(getCurrentUrl().contains("login_challenge"), "Wrong url found.");

In conclusion, is it common practice? No. Is it a good way to structure things? I don’t know.
In my opinion sometimes we just have to look at code as being code.
As long as everything makes sense, follows a familiar pattern, and has good documentation, then why not?
Most people already do use the WebDriver directly inside their tests, something that supposedly should be done exclusively in Page Objects.

What would be the disadvantages of having it set up like this?

1 Like

Consider the amount of work writing a test in relation to the amount of work maintaining it over the years. Maintenance takes far more of your time - with automation as with production code. So code should be quite clear to avoid the most ‘friction,’ and for that reason please do not extend a test class from a page class. Inheritance is meant to mean an “is a” relationship. And a test can use a page, but a test is not a page. Violating OOP principles is not a capital crime. But not following them can confuse people (others and even you, after a while) and slow them down in their work (and even cause mistakes).

The custom methods in the BasePage class are fine, I would say, especially for operations that are specific to the app. But I would expect them all to be protected then, because the (public) methods that are called from a test class should have a much higher abstraction level for page objects. If they are not app specific but just generic utility methods, I would prefer them in another class that focuses on interaction with the browser.


I wouldn’t be a fan of this decision for 3 reasons:

Again, this reduces the code we need to write

This is how all leaky abstractions get started. Sandi Metz was warning about this exact type of situation in her seminal the wrong abstraction.

You definitely should be reducing the amount of code you need to write but…not like that. You probably should be looking at doing it via encapsulation instead. You’ll save just as much code but won’t railroad yourself.

As an example of how it could go wrong - well, I had to write a test recently against a website that didn’t set up any pages with a browser. It was testing a security scenario.

1 Like