Base Test Class Testing Pattern: Why and How to use
This post belongs to the How to create Lean Test Automation Architecture for Web using Java series. If you didn’t see the previous posts, please check them out!
What is the Base Test Class?
It is a simple approach to set up common initialization and cleanup in your tests. We commonly categorize it as a Testing pattern.
The problem we are trying to solve here is the reuse of common behaviors across test classes avoiding coding duplication and centralizing these actions at one point.
The application of a Base test class, in OO programming languages, is applied by the use of inheritance.
Example without a Base Test Class
Let’s say you need to open the browser as a pre-condition and close it as a postcondition. Any test you create will have it, creating a code duplication.
Can you see in both test classes we have:
- On the lines 5 to 10 a pre-condition creating a new Google Chrome browser instance
- On line 14 a postcondition closing the Google Chrome browser instance
Both annotations were provided by JUnit 5.
@BeforeAll execute the code inside the method before all the
@Test methods before being executed.
@AfterAll execute the code inside the method after all the
@Test methods being executed.
As you can see we are duplication code, and it is a bad practice that neither does not scale your test not add less maintenance to it.
Example with a Base Test Class
The class below is Base test class implementation. You can notice the following:
- On line 1, you can see that the class is abstract, so we won’t be able to instantiate it, only extend it.
- On lines 5 to 10, you can see the test pre-condition we have used in the previous tests.
- On lines 12 to 15, you can see the test postcondition we have used in the previous tests.
As you can see we are avoiding the code duplication and adding the pre and post condition in a single class, so it will be a single point of change.
I have removed, in both tests, the pre and post condition, bu they will continue to run because I’m extending the test class by the
BaseWeb (the Base Test Class).
How it will be executed automatically?
Because we are using an annotation provided by JUnit 5. So, before the
@Test can run the pre-condition will be executed because it’s inherited from the
BaseWeb class. The same will happens with the postcondition.
Tips and more explanations
Why the class should be abstract?
You cannot instantiate an abstract class. So, we can declare methods with or without implementation and define fields that are not static and final. So abstract classes will provide:
- A way to share code among classes that needs the same behavior
- Need to use the same objects in the parent classes
- Need to modify the state of a shared object
We will not use abstract methods as, per definition, we must implement in the parent class. We are going to write abstract methods with implementation to be able to override them if you want, giving you more flexibility.
Take advantage of initialization and cleanup methods from unit test frameworks
As you can see I used the pre and postcondition approach from JUnit 5. You can take advantage of these features to write a clean and maintainable test.
You can learn the pre and post conditions implementations from:
- JUnit 5: https://junit.org/junit5/docs/current/user-guide/#writing-tests-classes-and-methods
- TestNG: https://testng.org/doc/documentation-main.html#annotations
I don’t need to use pre or postcondition (one or another)
If do you need, by any change, not execute the pre or postcondition (in the scenario you need to use the Base Test Class) you can simply override the method removing the
super reference, making it empty or adding your custom implementation just for that test.
But bear in mind if you need to do it in many test classes you might end up with a new Base Test Class, and it’s ok. Personally I never saw different ones for a web test approach, but I’m using different ones for the API tests.