Test automation framework architecture efforts are often complete failures.
It’s true. I’ve worked with many companies who have given up on creating a good test automation framework architecture, because after investing a large amount of time and money and resources in doing it the wrong way, they have incorrectly assumed the entire effort is not cost effective.
In this post, I’m going to simplify the process of creating a test automation framework architecture and show you that—if you do it right—it can be a very good investment.
Test automation framework architecture basics
Let’s start off by talking about what the goals of a successful test automation framework architecture should be.
There are two goals I am interested in when creating a test automation framework:
- Having the ability to easily create simple automated tests that use the framework.
- Decoupling cosmetic application changes from the tests so that when the application changes, the tests do not all have to be updated
A good test automation framework architecture should at the very least provide these two important services. We create a test automation framework to allow us to support the creation of tests and to keep those tests from being dependent on the actual UI of our application—as much as possible.
I’m going to break down these goals just a little more to make sure we are all on the same page.
Creating simple automated tests
First, we’ll start with having the ability to easily create simple automated tests that use the framework. Why do we care about this goal? And why would this be the responsibility of the framework?
I have found that one of the biggest failure points of test automation efforts is test complexity. The more complex the tests are, the harder they are to maintain. If tests are difficult to maintain, guess what? They won’t be maintained.
So, we really want to make sure that when we create a test automation framework architecture, we focus on making sure that test automation framework makes it as easy as possible for someone to create tests using it.
It is always a better choice to put the complexity into the framework instead of into the tests. The framework is usually maintained by developers and does not contain repeated code. But, tests are often created by QA or even business folks and the code found in tests is usually repeated across many tests, so it is vital to reduce the complexity on the tests, even if it means a large increase of complexity in the framework itself.
When I create a test automation framework architecture, my goal is to make it so the tests can read as close as possible to plain English. This requires some effort to pull off, but it is well worth it.
Decoupling the UI from the tests
Next, let’s talk about what I mean by decoupling cosmetic application changes from the tests.
This is also a vital goal of any test automation framework architecture, because if you fail to decouple the UI of an application from the tests, every single UI change in an application will cause possibly hundreds or thousands of tests to have to be changed as well.
What we really want to do is to make it so that our test automation framework architecture creates an abstraction layer that insulates the tests from having to know about the actual UI of the application.
At first this seems a little strange, especially when I tell automation engineers or developers creating an automated testing framework not to put any Selenium code into their actual tests.
All of the Selenium examples show you creating tests that directly use a web browser driver like Selenium, but you don’t want to write your tests that way—trust me on this one.
(By the way, I haven’t found a good book on creating an actual test automation framework architecture—I’ll probably write one—but, for now if you are looking for a good book on Selenium that starts to go into the topics I discuss here, check out Selenium Testing Tools Cookbook.)
Instead, what you want to do is to make it so the test automation framework is the only code that directly interacts with the UI of the application. The tests use the framework for everything they want to do.
So, for example:
Suppose you are creating a simple test to check to see if a user can log into your application.
You could write a test that looks something like this: (C# and Selenium in this example)
var loginInput = driver.FindElement(By.Id("txtUsername")); loginInput.SendKeys("Joe"); var passwordInput = driver.FindElement(By.Id("txtPassword")); passwordInput.SendKeys("$ecret"); var loginButton = driver.FindElement(By.Id("btnLogin")); loginButton.Click();
But, what is going to happen when you change the ID of your “User Name” field? Every single test that uses that field will break.
On the other hand, if you properly create a test automation framework architecture that abstracts the UI away from the tests themselves, you would end up with a much simpler and less fragile test, like this:
Now, if the ID of your “User Name” field changes, you’ll just change the code in your automated testing framework in one place, instead of changing 100 tests that all depended on the specific implementation of the UI.
A simple test automation framework architecture
Once you understand those two very important goals and why they are important, it is easier to think about how you should design a test automation framework architecture.
I’ve created quite a few test automation framework architectures, so I’ll give you a basic design I use for most of them.
Take a look at this diagram:
Here you can see that there are four layers to my test automation framework architecture.
Frist, we have the browser layer or the web app itself. This just represents your actual application.
Next, we have the Selenium or web driver layer. This layer represents your browser automation tool. Selenium is basically just a framework for automating a browser. It doesn’t know anything about testing, it is an API that lets you interact with the browser programmatically. (By the way, you don’t have to use Selenium. I just use it as an example here, because it is the most popular browser automation framework.)
After that, we have the framework layer. This is the actual framework you create which uses Selenium, or whatever web driver you want, to actually automate your application. The framework is acting as an abstraction between your application and the tests. The framework knows about the UI of your application and how to interact with it using Selenium. It is your job to create this layer.
Finally, we have the actual tests. The tests use the framework to manipulate your application and check the state of the application. These tests should be simple to understand and should not have to know anything about the actual implementation of the UI of your application. These tests should rely on the framework to give them the ability to do whatever they need to do in your application.
Obviously, creating a test automation framework architecture is more complicated than what I have shown you in this article, but with these basics you should be off to a good start.
If you want a more in-depth and detailed explanation as well as an example of how exactly to create a full test automation framework architecture, you might want to check out my Pluralsight video on the topic:
I also frequently blog about test automation topics and other topics related to becoming a better and more profitable software developer.
If you have any question, post them in the comments below.