Select Page
Selenium Testing

The Must-Know Selenium Best Practices for Successful Test Automation

Facing Failures in Selenium Automation? Our Comprehensive List of Selenium Best Practices will help you overcome all the challenges.

The Must-Know Selenium Best Practices for Successful Test Automation - Blog
Listen to this blog

Over the years, Selenium test automation has become an integral part of quality assurance. Despite its immense popularity, many might have faced various difficulties in the form of flaky and unstable tests. But does that imply that the issue is with Selenium? Being a leading test automation services provider, we have no second thoughts in its capacity and can firmly say that everybody can get the best out of it if they follow the best practices. Though there are no specific rules for creating your Selenium test automation scripts, these Selenium best practices will definitely act as effective guidelines. So in this blog, we have listed the Selenium best practices that one can follow to enhance the efficiency of their Selenium Test Automation.

Know Which Tests Should Be Automated

It is a well-known fact that 100% automation isn’t possible. So trying to automate every single scenario or automating every scenario that can be automated is not the best approach. So before you kickstart your automated browser testing, make sure you are clear of what tests have to be automated. When it comes to automation, always keep in mind that just because you can do something doesn’t mean that you should do it.

So start off by designing effective test cases before you start working on automation. Apart from that, analyzing if automating a scenario will result in the reduction of repetitive and tedious tasks is also crucial. So if you automate a test case that doesn’t have much frequency of occurrence, then spending that much time and effort on automating the test case is not validated. So as a first step, look for static test cases that have predictable outputs.

Choose the Best Locators

Since Selenium has a wide range of web locators available, choosing the best locators can impact the quality of your Selenium test automation. Some of the most often used web locators in Selenium WebDriver are

  • ID
  • Class
  • tagName
  • Name
  • Link text
  • XPath
  • CSS Selector
  • DOM Locator, and so on.

It’s important to pick the proper one as it will reduce the impact of user interface changes during testing. For example, if there is a dynamic scenario, link text will generally be preferable. But if you are looking for web locators that are less brittle, ID, Class, or Name would be the way to go even though it isn’t that user-friendly.
To learn more about the many ways to locate web elements and to know which locators are most suited for specific scenarios, read our blog about the different XPath methods in Selenium.

Utilize time-efficient approaches

It is not always about getting the script to work as your test scripts should also be efficient when executed. What might feel like just a few seconds will definitely have huge impacts when you have to execute the tests numerous times in different combinations. That is why we have incorporated the following Selenium best practices that will help you save loads of time.

Use Selenium Wait Commands Instead of Thread.sleep()

Various factors like network slowness or server issues can cause your web application to take additional time to load. So your automation scripts should be able to wait for all the elements to load before starting the test execution.

The Thread.sleep() method can be used for this purpose as it can pause your script for a specific amount of time.

Sleep

Sleep() waits for the number of seconds supplied in the brackets, regardless of whether the working page is ready.

There is a major flaw with this function as the script will wait for a fixed time for every scenario irrespective of the need. For example, let’s assume that you have set the sleep time to be 6 seconds. But what if the webpage that has to be tested loads in just 3 seconds? Or what if the webpage took 7 seconds to load? You will either be wasting time or getting inaccurate results because of this approach. But you can prevent such issues by utilizing implicit or explicit waits.

Wait

Explicit: The code execution is halted until a certain condition is satisfied.

Packages to import to use the Explicit wait

import org.openqa.selenium.support.ui.ExpectedConditions
import org.openqa.selenium.support.ui.WebDriverWait

Code to initialize a Wait Object using WebDriverWait Class

WebDriverWait wait = new WebDriverWait(driver,10);

Here WebDriverWait is the class, and new is the reference variable. It will either for the defined amount or for the expected condition to be fulfilled. This is just a sample and you can use the same concept with the other available expected conditions. Though there are various options, we have listed a few below,

  • visibilityOf()
  • alertIsPresent()
  • titleContains()
  • textToBePresentInElement()
  • invisibilityOfTheElementLocated()
  • elementSelectionStateToBe()
  • elementToBeClickable()
  • presenceOfAllElementsLocatedBy()
  • frameToBeAvaliableAndSwitchToIt()

Example:

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(text(),CODOID)]")));

By now you would have understood why we have included the usage of the wait commands in our list of Selenium best practices. Beyond the explicit wait, there are also implicit and fluent wait commands that give you more options. So let’s explore them now.

Implicit: The WebDriver is advised to keep polling the DOM until the element search is complete. By default, the time is set to 0.

Syntax

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Fluent: It waits for a specified maximum amount of time for a specific condition. What makes it different is that it will validate the element at regular intervals before throwing “ElementNotVisibleException”.

Syntax

Wait wait = new FluentWait(Webdriver_Reference)
.withTimout(timeOut, SECONDS)
.pollingEvery(timeOut, SECONDS)
.Ignoring(Exception class)

Sample Snippet

We have mentioned a sampe snippet that will wait for 30 seconds and check the condition every 5 seconds.

FluentWait wait = new FluentWait(driver);
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement) {    
    public WebElement apply(WebDriver driver) {    
        return driver.findElement(By.id("element"));    
    }
});

Implicit: The WebDriver is advised to keep polling the DOM until the element search is complete. By default, the time is set to 0.

Use Assert and Verify-in Appropriate Scenarios

Let’s assume that there is a task to transport 100 boxes of apples to the market. But what if all the boxes of apples are rotten already? Will there be any use in putting all the effort and time to get the apple to the market only for it to go unsold? Likewise, there will be various scenarios where there are hard fails that will compromise the rest of the execution. Please keep in mind that Asserts should only be used if you want to stop the test execution when a hard failure occurs. If the assert condition is false, the execution will come to a halt, and no more tests will be run. So it is important to identify such bottlenecks and ensure that you use Asserts to save time.

If we take an e-commerce site as an example, such scenarios might come at the very beginning where a user is unable to login, or even in between where the user isn’t able to add any product to their cart. If these functionalities fail, there will be no point in testing the search functionality or payment process as it would all fail due to their dependency.

If the errors are not that critical, then you will be able to run the tests irrespective of the verify’s condition.

Increase Test Coverage

There is just no easy workaround when it comes to testing a website or an application across a variety of devices and browsers. The devices are further split based on the operating system they use as well. So let’s take a look at a few Selenium Best Practices that will help you increase the test coverage.

Browser Compatibility Matrix

Just like knowing what to automate, it is important to figure out the high-priority combinations that are used by your target audience. So create a Browser Compatibility Matrix by performing a product analysis to obtain detailed insights. Trying to perform automation testing with Selenium without narrowing down your target will not only be a cumbersome task, but it will also be a waste of time and resources.

Make use of Parallel Testing in Selenium

Though you are able to narrow down the device combinations, you will not always have the time to test everything one by one. Since Selenium’s parallel testing option is a major reason for its popularity, you can employ it not just to save time, but to also improve your test coverage in an efficient way. Almost all major test frameworks, such as PyTest, PyUnit, TestNG, Cucumber, and so on support simultaneous testing on a Selenium Grid. If you are not familiar with the concept of creating a Selenium Grid for distributed execution, make sure to read our conclusive blog.

Being the innovators we are, we even developed an open-source tool called VisGrid that will provide you with a UI to easily start a Selenium Grid, create & attach nodes, and so on.

Use many driver implementations instead of a single one

Since Selenium’s WebDrivers are not interchangeable, executing automated cross-browser tests on a local computer is not the same as running them on a continuous build server. It would be a mistake to assume that the following test will utilize Firefox WebDriver in that situation (or Chrome WebDriver or any other WebDriver).

When running integration tests in a continuous build environment, the test will only get a RemoteDriver object (i.e., WebDriver for any target browser). Using parameter notes to manage multiple browser types and prepare the code ready for simultaneous execution is one of the Selenium best practices (or parallel testing). LabelledParameterized (@Parameters in TestNG and @RunWith in JUnit) may be used to build small frameworks in Selenium.

Ease Code Maintenance

When working on automation tests with Selenium, it’s critical to pay attention to the test code’s maintainability and reusability. As one of the best test automation companies, we always make sure our scripts are easy to maintain by implementing the following Selenium best practices.

Use design principles and patterns, such as the Page Object Model

With the ever-increasing client expectations, a website’s user interface (UI) will inevitably change as new updates get introduced at regular intervals. So the locators for certain UI components will vary as well. This implies that QAs have to once again create new test cases for the same page or make numerous changes at various places of the script, which can be time-consuming.

So you can employ the Page Object Model design pattern to create test scripts and overcome this issue. In this approach, each web page is considered a class file in the design pattern, and each class file contains related web components.

This method greatly increases the reusability of the code while also making test maintenance easier. Read our complete guide to page object model in Selenium before you implement it.

Quarantine flaky tests

If a test keeps failing at random even if the code hasn’t gone through any changes, then it is called a flaky test. Since the testers can never be sure of the results, they will lose trust in the code and end up re-running the scripts, or debugging the scripts even though there might not be an actual defect. So make sure to quarantine such tests from your other tests. Once they are separated, make sure to analyze them and fix them before you bring them back to your test suite as flaky tests can disrupt your entire automation test suite with false positives and negatives.

Wrap Selenium Calls

You might be using various web locators such as XPath and ID to locate different web elements on the page. So the code that is regularly used in the implementation should be separated into its own API to reduce code duplication. By following this approach, you will be able to reduce the code size and enhance maintainability.

Use a standardized directory structure

Page Objects, Helper functions, and file(s) that include web locator information needed in test scenarios may all be found in the Src folder. The actual test implementation can be stored in the test folder.
When it comes to a directory structure for Selenium test automation, we don’t have a common guideline. Selenium best practices, on the other hand, proposes that we have a directory structure that isolates the test implementation from the test automation framework. This improves the test code’s structure.

Implement Data-Driven Testing for Parameterization

Hard coding test values in test automation scripts are extremely troublesome and not scalable in any way. But you can avoid the various disadvantages like code duplication by implementing data-driven testing by using Parameterization. It aids in the execution of test cases that have a variety of inputs (or data sets).

Naming Convention

Improper naming of your web elements in your automation script could lead to a lot of unnecessary confusion. You may not face any issues as long as you are the only person using the script, but you have to ensure that your script can be used by anybody. Effective naming eases code maintenance by also making it easier to find the web element you are looking for in your code. Now let’s see a few tips that can help you.

1. Add prefixes to the name of your web elements as shown in the below table as it describes the type of web elements being used. In addition to that, you can name the web element based on how it appears in the UI.

S. No Web Element Type Prefix Example
1 Text Box Txt TxtUsername,TxtPassword
2 Button Btn BtnSignUp , BtnLogin
3 Drop Down Dd DdCountry , DdYear
4 Select Drop Down Sdd SddMonth , SddYear
5 Check Box Chk ChkGender, ChkLanguage
6 Header Hdr HdrName, HdrUser
7 Table Tbl TblBooks, TblProducts
8 Label Lbl LblUserName, LblPassword
9 Image Img ImgProfile, ImgCart

2. You can even add prefixes that denote the action to be performed on the web element.

Example:

S. No Action Prefix Example
1 Click Clk ClkLogin, ClkIcon
2 Type Set SetMobileNo, SetPassword
3 Verify Verify VerifyLogo
4 Check A Check Box Chk ChkLanguage
5 Select Value From Drop Down Select SelectCountry, SelectZone

3. Likewise, you can make use of suffixes when creating action pages.

Example:

SignUpPage

LoginPage

4. To make it even clear, you can use a camel case to name the web elements.

Camel case is nothing but a typing convention like lower case and upper case in which the first letter of every word is capitalized.

Example:

If a text box has the label as “Email address”, name it as “txtEmailAddress”

Proper Documentation

Creating proper documentation for your automation tests in Selenium is as important as any of the other Selenium best practices we have discussed thus far.

Use Automated Screenshots to Analyse Failures

Automation Test Script running into failures is an eventuality. But we will not be sure if the failure is due to a defect in the Application Under Test (AUT) or if there is a problem with our code. So analyzing the cause of a test failure will be very crucial, and so taking screenshots is a best practice that can save a lot of time. Screenshots are not just great for failures as you can make use of screenshots as evidence for success.
To capture a screenshot, use the getScreenshotAs function in the following code sample.

File source = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("Test Screenshot.png"));

Log and Report

Finding that one failed test case in a large test suite is like finding a needle in a haystack. So using console logs at suitable points in the test code helps us understand the issues better and zero in on the core problem.
Debug, info, warning, error, and critical are some of the common log levels that are available in most programming languages. Since adding unnecessary logs to the test implementation might cause test execution to be delayed, it is better to add logs with level errors in scenarios that enable easier tracking.

Like logging, reporting is also an important aspect of Selenium test automation as it helps determine if the test has passed or failed. You can also keep track of the progress of test suites (or test cases). This in turn helps improve the readability of the output and helps you reduce the amount of time spent maintaining test data as you can easily analyze the features and test coverage.

Set Zoom Level to 100% and Maximize the Window

Make sure to set the zoom level in your browser to 100% during your automation as it is one of the basics that should be followed regardless of which browser you opt to use. It will both provide a native mouse experience and ensure that the native mouse events are assigned to the proper coordinates.

Ensure to maximize the window as soon as the test URL is loaded as Selenium doesn’t launch the browser in the maximized mode by default.

Snippet

driver.manage().window().maximize();

Conclusion

We have seen great results by implementing these Selenium best practices in our automation testing projects and hope you will them useful in the future as well. We had listed various Selenium best practices under particular categories to enable a crystal clear understanding of how each of them impacts the testing process on the whole. So we hope you have enjoyed reading our blog and found the content to be informative as well.

Comments(0)

Submit a Comment

Your email address will not be published. Required fields are marked *

Talk to our Experts

Amazing clients who
trust us


poloatto
ABB
polaris
ooredo
stryker
mobility