The abstraction layers are ruining your test automation framework
Why they have such an impact in your testing efforts
๐ If I had to choose just one thing to talk to you about how you should design your test automation framework, that definitely would be abstraction layers. Let's dive into how you can benefit from this concept so you can build solid foundations in your framework. ๐๏ธ While the background for this article is a .Net
C# solution, the ideas discussed here can be applied to several programming languages.
๐จ Definition
Abstraction layers in a framework are essential for segregating responsibilities between classes when designing your solution. These layers help maintain a clear distinction between high-level abstractions, which encapsulate the business rules of your application, and low-level abstractions, which are more closely tied to implementation details.
In software engineering, it's a best practice to position high-level abstractions closer to the surface of your solution, while low-level abstraction classes reside deeper within the architecture. This ensures that the core business logic remains easily accessible and understandable, while implementation details are encapsulated and modularized.
This topic is really important for designing software. Learning more about abstraction layers will help you get better at creating software that's strong and easy to maintain. ๐งฑ
๐ ๏ธ Step Classes
After the feature files that we learned about previously, come the step classes. Acting as a link between specifications and your automation solution, they map business rules into functions. It should be no secret that such classes are meant to be very high level. However, people still make mistakes at this point when they don't have an efficient framework design. Let's talk about testing our feature using the browser. Keeping that in mind, I will show a couple methods as an example and highlight some interesting thoughts about them.
๐ซ Example you should avoid
[Given(@"I add (.*) to my shopping cart")]
public void GivenIAddItemToCart(string myItem){
// code directly interacting with WebDriver
_driver.FindElement(By.CssSelector($".{myItem}"))
_driver.FindElement(By.Id("add-to-cart-button")).Click();
}
๐ ๏ธ The Clever Tester solution
[Given(@"I add (.*) to my shopping cart")]
public void GivenIAddItemToCart(string myItem){
// an injected facade class object
_shoppingCartService
.SelectItem(myItem) //smaller business rule
.SelectQuantity()
.AddToCart();
}
Decouple Step Classes from WebDriver and Selenium: To ensure flexibility and maintainability, forget about directly integrating WebDriver or Selenium within your step classes. Instead, employ Facade classes through dependency injection. These Facade classes act as intermediaries, shielding your step classes from direct dependencies on specific testing engines and unnecessary implementation details.
Embrace Natural Language and High-Level Abstraction: Keep your step classes aligned with natural language and free from programming logic such as loops and conditionals. This approach enhances readability and simplifies the evaluation of test step methods.
Implement Fluent Design Patterns: Although not obligatory, integrating fluent design patterns into your step classes can significantly enhance code readability and maintainability. Fluent interfaces facilitate a more expressive and intuitive interaction with your testing framework.
Enforce Single-Operation Principle: Ensure that each method within your step classes is encapsulating a functional module within your application's domain, make sure you also decompose the step into smaller business rules if required. This adherence to the single-operation principle fosters modularity and clarity within your test scripts.
By adhering to these guidelines, you can streamline your testing process and promote code maintainability and scalability.
๐ Conclusion
The most remarkable characteristics that your testing automation framework design should be embedded with, such as scalability, readability, maintainability, and others, will directly impact the costs of your testing efforts. Having the correct foundation will define how solid your project is on the long run, so make sure you invest the right amount of time on getting it right and you should thrive. ๐ช