December 11, 2018

What software design principles do you use writing UI automation frameworks? Do you use SOLID?

When crafting automation frameworks, do you use SOLID software design principles in your work? If so, could you provide some examples?  

Ever since I've been tasked to create a Capybara + Ruby UI automation framework, I've been reading  books such as Robert "Uncle Bob" C. Martin's Clean Architecture: A Craftman's Guide to Software Structure and Design (2018) and his Agile Software Development, Principles, Patterns, and Practices (2002), trying to glean some insight on how to improve what I am doing.

The SOLID object oriented design principles, a mnemonic created by Michael Feathers based on principles Uncle Bob had collected are a bit beyond me at the moment. Attempting to study about the Single responsibility principle, Open/closed principle, Liskov substitution principle, Interface segregation principle and the Dependency inversion principle, trying to see how I can apply them is giving me a headache.

I fully recommend Angie Jones' webinar, Applying the Pillars of Object Oriented Frameworks to Test Automation for anyone who needs a refresher on Encapsulation, Inheritance, Polymorphic and Abstraction. I wish there was something like this for SOLID design principles!

Here are some of the principles I follow when writing automation frameworks:

DRY
  • Don't Repeat Yourself.  Instead of copying-and-pasting code, I factor out commonly used code snippets, placing the block of code into a library I can then reuse. 

YAGNI
  • You Ain't Going To Need It. Instead of plotting out every single selector on a page that locates a web element in a user-interface, I focus on just what I need for the current two week sprint. Every single time I try to plan ahead, priorities change, shift, reshape, and by the time I finally get back to the prepwork, everything has changed.

Abstraction
  • If there is a Login screen, I create a Login page object, which stores all the locators that interact with the web elements such as the username & password textbox, and the Login button. It also would have a LOGIN method where a test could pass in a username and password and be logged into the System Under Test.

Encapsulation
  • Within Page Objects, I declare public methods that then interact with the private variables storing the selectors for the web elements on the page. 

Inheritance
  • Are there commonly used elements on the page? I create a Base Page Object which contain commonly used methods that other pages can inherit.
These principles? I find them easy to understand and use. SOLID Principles? Not so much.

Any help that you could give would be much appreciated. I will craft a response blog post from the answers I receive. 

Oh, and don't get me started on how lost I am about the Gang of Four's Design Patterns: Elements of Reusable Object-Oriented Software (1994)!



Happy Testing?

-T.J. Maher
Sr. QA Engineer, Software Engineer in Test
Meetup Organizer, Ministry of Testing - Boston

Twitter | YouTubeLinkedIn | Articles

1 comment:

Nikolay Advolodkin said...

Hey TJ,
Thanks for that article and this is a great conversation that you've started.

I still owe you an article on SRP, which I believe to be the easiest to use and one that has drastic impacts on test automation. OOP is also good to keep in mind as we design systems. I find it extremely useful when dealing with switch statements. Right away when I have switch statements I know that they are breaking OOP principle, so I replace them with factories.

The other ones, I keep in mind but I rarely find use for them. DIP is extremely useful if you are trying to write a system that is unit testable. Sometimes I found myself needing to write unit tests for some of my methods that get more complex. In that case, DIP is useful because it allows me to inject mocks or stubs into my unit tests.