We all know by now that the benefits of test automation are clear. Many QA projects start small and gradually gain complexity due to new features flowing in. By then, you find yourself handling a test suite that only increases in terms of the # of tests that you need to run in a given period and the time it takes to complete them.
In agile environments, this phenomenon is accelerated.
That’s where automation comes in. Still, having a test automation operation doesn’t mean having an optimal one.
By the way, this topic gets attention in communities such as Github, StackOverflow, and alike. It is a topic that is interesting for Selenium coders, beginners, or experienced.
An efficient automation framework, just like a good cooking recipe, provides testers with guidelines to leverage reusable automated tests rapidly and reliably to achieve specific testing goals.
So, where should you start?
Here is my ‘9-step guide’ for getting started with an efficient automation framework:
- POMs:
- Use a page object model (POM). Why? Cause it’s easy to use, reliable, readable, and most importantly, reusable.
- If there are some changes in your UI, you’ll have to make the changes only in one class that represents the changed component, instead of changing it in 10 separate tests that use the same page (which you’ll find yourself doing if you don’t use a POM).
- Separate between locators, actions on elements, and the test itself.
- Tests become shorts as we reuse POMs and their methods.
- Driver Manager
- Build a class to manage drivers with multiple threads, for example:
public class LocalDriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
public static WebDriver getDriver() {
return webDriver.get();
}
static void setWebDriver(WebDriver driver) {
webDriver.set(driver);
}
}
- Build a class to manage drivers with multiple threads, for example:
- To use the driver in tests, you can use:
LocalDriverManager.getDriver(); - Abstract POM
- Build an abstract POM that all your POMs will extend
- Initialize Webdriver in your abstract POM:
protected WebDriver driver = LocalDriverManager.getDriver();
- Initialize Webdriver Wait
protected Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(20, TimeUnit.SECONDS).pollingEvery(900, TimeUnit.MILLISECONDS);
- Initialize Page factory, for example:
PageFactory.initElements(new AjaxElementLocatorFactory(driver, 4), this);
- Add abstract isDisplayed function that every derived class must implement, for example:
public abstract boolean isDisplayed();
- Waits
- Use waits wisely: It’s better to use explicit waits instead of implicit waits.
- Avoid using Thread. Sleep (), sometimes this sleep is sufficient, but it’s not enough when the application is too slow, so using explicit wait is much more efficient.
- Make your code generic.
- As I mentioned earlier, build your POMs and tests to be generic and reusable.
- Keep using common classes and common methods, and don’t duplicate your code.
- Suites
- Create an XML suite for every section in your website, so when you want to test that section, you can run only that specific suite instead of running all the tests.
- Create a Sanity suite and a Full Regression suite. The Sanity should test all sections but should be a fast run to test that your website isn’t broken, and the Full Regression is there to test all the sections deeply.
- Use CI/CD tools
- Run all your tests at night-time, every day, so in the morning you’ll have the report ready for you.
- Run your tests every few hours so you can keep your tests stable for a longer period of time
- Assert EVERYWHERE
- After every action, I suggest you add an assert, so most of the failures are on the assertion.
- Don’t assume anything. Before using every POM, always use assert with pom.isDisplayed()
- Always add an informative assert message so that everyone can understand the cause of the failure.
- Screenshot
- If the assert didn’t help you, the screenshot could help
- Add ‘take screenshot’ to @aftermethod, but only on failure. For example:
@AfterMethod(alwaysRun = true)
public void screenshot(ITestResult result){
if (result.getStatus() == ITestResult.FAILURE){
takeScreenshot(driver);
}
}
public static void takeScreenshot(WebDriver driver) {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
//Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));
}
To sum it up…
If you build your automation framework based on these 9 steps, you’re most likely to find yourself gaining more accurate automated tests, reducing the product release time, and most importantly, you’ll improve the products’ time-to-market.
Or: you might explore RadView TestAutomation, which provides you with a plug-n-play test automation framework every time you start a project.