Automation Framework design patterns:
Before we understand Automation Design patterns we first need to understand the components of an Automation Framework.
I broadly categorise them in 6 major parts as below:
- Driver
- Configurations
- Objects
- Tests
- Utils
- Generic Utils
- Business Utils
- Logs
- Reports
Central Idea in automation FW design: These components of the FW should be separated from each other. Each component should be built on “Request and Response” architecture. Where-in one component should be able to request service from other component and this “called” component should answer the call.
To achieve this you can make use of existing coding design patters like Builder, Factory, Singleton design patterns, or your customised design patterns.
Irrespective of what ever you use, idea of segregation should be maintained and no intermingling of the components should be allowed.
Details on these components are as follows:
- Driver:
- Abstract Idea: Something which drives your FW. It is also the Starting point of your FW. Other than responsible for trigger, it also have/should have features to control the execution flow; i.e. which test case to run, which not run, in what sequence and also with what data and configurations; all this should be controllable from a Driver.
- How this is being implemented across market standard FWs:
- TestNG: Test NG is a FW which has implemented browser feature in the form of driver.xml. This XML has all the above stated features. It can be used to pass parameters as well as configurations like URLs, Credentials, browser configurations. You can also manage which test groups/modules to execute etc.
- Cucumber BDD: Similar features are available with Cucumber FW, which has become a leading FW across industry. Execution flow in Cucumber is controlled by combinations of Feature files and cucumber options, tags etc.
- Configuration: A configuration is a component which lets you configure the FW based on the Environments, data, Credentials, Browser Information, Driver Info etc. Can be implemented using an Excel file, Properties file, Test NG XML file if using TestNG FW, Maven POM file can also be used for configurations.
- Objects: This is the most important component of the FW. This component could really decide the success and failure of your framework for any UI framework. For an API or DB FW, this component is not required however. Its about how you structure your page objects. There are many ways to implement this Object repository concept. Object repository concept is present in nearly all the major enterprise automation tools like HP UFT, SmartBear TestComplete etc. But if we talk about Selenium in particular we do not have such implementation out of the box. So how do we implement it? Well there are many ways, keeping in mind the centralisation concept i.e. all the objects has to be at a centralised repository. Few of the Ways are:
- Add all the objects in an Excel file.
- Use properties file to add object locators.
- Use XML
- Page Object Model
- Page Object Model-Selenium Page Factory.
- Object Repository/Page Object Model: However, we can further bifurcate this centralised repository in sub levels based on some predefined structure. Best way to manage, which is also an industry standard recommendation is to use Page object Model. Now again page object model can be implemented in multiple ways. Selenium as an API provides a feature called as page factory to implement page object model in your FW. Idea is page object model is three fold:
- Divide your page Objects or locators on logical lines i.e. pages.
- Each UI page objects which are unique to that page should reside in a corresponding Java/Python class file. Objects which are common i.e. Menu Links etc should have a separate page object file.
- Objects under these class files should be private that is no one should be able to access them directly, rather create methods in side these class files which would act as an agent and should be callable from your tests.
- Tests: This holds your automation test scripts. This should hold only business logic, no loose code, no configurations. TestNG FW provides @Test annotations to provide control over what will be executed and in what sequence. Similarly, Cucumber FW hides all the un-necessary details and we write plain english to create test cases. For example, if a test case is to test login feature of the application, it should only have these steps:
- OpenNewBrowser
- NavigateURL
- EnterUserName
- EnterPassword
- ClickSubmit
- ValidateLoginIsSuccessfull
- Utils: Utils are to place your common libraries. These libraries are created to help the test creator in writing tests faster, cleaner and when every one uses the same method to perform a specific task in the test, it gives maintainer/architect enough power to control whole FW i.e. merely by making a change in a specific method he/she could manipulate the behaviour of the tests. This reduces maintenance work greatly. You can create and split Utils in two ways, one generic and other business level. Generic Utils deals with all the general purpose tasks like, UI Interactions, Excel manipulation, DB connection, DB operations etc. Business Utils are to deal with common business operations like Navigating, Login, Search operations, Test data creations etc
- Logs: This is by far again the most important segment of the FW. If this is not implemented well enough, it becomes so difficult or impossible sometimes, to figure out what went wrong during the execution. Idea behind this component is simple however, log everything you framework does. Why? because when things go south its your logs who comes for your rescue. From logs you can figure out where was the error, what is the nature of the error etc. Usually you need this only while debugging issues (which happens a lot, trust me!). We have many API’s to implement logging. Log4j, SLF etc are many such tools. Other than that almost all the FW like test ng , cucumber provides mechanisms to implement logs.
- Reports: This is the final output of your framework. This is reason we implement an automation framework. Logging is actually of two types, High level and low level. Low level logs contains all the micro level information about the execution as explained above. High Level logs is actually called as Reports, which usually has a dash board representing how many test case passes, failed, not run etc. It also has details on steps status per test case and screen shot evidences. Purpose of having this is so that the report makes sense to every one including Testers, Dev, BA, Product Owner, any other stake holders. Again there are many open apis to do that. Test NG, Cucumber has their own reporters. Then we have an API called as Extent report which provides a very good HTML reports. Serenity FW which has been build on top of Cucumber is again a FW which provides very good HTML report.
Conclusion:Yet to be written