Selenium Best Practices

Best Practices of Selenium 

The Selenium automation framework is a great tool-set for automating interactions with the browser. Because of its powerful open source features and standard adoption across many browsers, Selenium has become the most popular web testing framework in the world. You can run your automated testing scripts in a variety of languages against local browsers, a lab of browsers and devices using Selenium Grid or a device cloud like CrossBrowserTesting’s. To get the most out of Selenium automation, we’ve put together five best practices for automated browser testing.

Use The Right Locators

At the heart of the Selenium framework is interaction with the browser, letting you navigate, click, type and check different objects within the DOM using a few set actions. It does this using several different types of locators:

Class

ID

Link Text

PartPartial Link Textial

Tag Name

X Path

Selecting the right locators can be the different between a test script that is flexible and successful, and a brittle test that breaks on the slightest UI change. If they are present, use unique Classes or IDs as Selenium locators, as they are less likely to change without someone on your QA or Dev team knowing. But locators like link text can change all the time – think about a dynamic button based on logged in state, or your marketing team running A/B tests. You can also use Xpath to navigate the webdriver, you can read more about Xpath to CSS conversion here.

Preferred selector order: id > name > css > xpath

To locate an element we can use

the element’s ID

the element’s name attribute

an XPath statement

by a links text

document object model (DOM)

id and name are often the easiest and sure way.

xpath are often brittle. For example you have 3 tables displayed but sometimes there are no data and the table isn’t rendered, your xpath locating the second table will not always return the intented one.

css are the way to goin conjunction of id and name !

Locating links in an internationalized application is sometimes hard… try to use partial href.


Communication Between QA, Developers, Marketers, and Designers is Key

There are two aspects of collaborating with different teams that can make your Selenium testing a success: constant communication and instilling the importance of testing to every department. Instilling the importance of the QA process on your development team can save time and efficiency when building a testing framework. Make sure they know how important unique CSS selectors are to your testing efforts, and ask them to write semantic and human-friendly code. Having constant communication across teams can help QA plan for changes to the UI of a website or application mandated from Marketing or the Design team. Having small conversations about the front-end aspect of your app decreases the chance of surprise UI changes that will go untested.

Page Object Model. Use it.

A popular test automation design pattern, the page object model will help you make robust testing frameworks that are resistant to small tweaks in the UI. The page object model has two core advantages:

There is clean separation between test code and page specific code such as locators (or their use if you’re using a UI map) and layout.

 There is single repository for the services or operations offered by the page rather than having these services scattered through out the tests.

Make Tests Independent Of Each Other

Testing one single action or process, independent of any other tests is known as atomic testing. This testing strategy will keep you from making chained, brittle tests. Chaining together tests, while saving time upfront, can be a huge hinderance to an agile or CI workflow. Keep tests as small as possible.

Use Your Resources

Selenium can be tough to learn because it requires a certain amount of tangential knowledge. You have to have some understanding of programming and to truly be a skilled Selenium tester, an understanding of test automation best practices. Luckily, there are some fantastic resources available on the internet to learn from. While we run monthly webinars to get you up and running with Selenium.

https://www.seleniumhq.org/

 Avoid Thread.sleep prefer Wait Instead of sleep

public void clickOnContactType() {

getDriver().findElement(By.id(“contacttypelink”)).click();

sleep(500);

}

Use Wait

(new WebDriverWait(driver, 30)).until(new ExpectedCondition() {

public Boolean apply(WebDriver d) {

return d.getTitle().toLowerCase().startsWith(“Java Developer”);

}


AjaxTableElement


If you use table elemenst with paging, sorting,… you can perhaps create a component AjaxTableElement

add in pageObject :


public class CampaignSearchPage extends AbstractPage {

     ....

     public AjaxTableElement getTableResult() {

    return new AjaxTableElement(getDriver(),"results");

  }

}

Then you can use the AjaxTableElement

page.searchFor(param);

page.getTableResult().hasResult();

page.getTableResult().clickOnResult(1);

Don’t rely on specific Driver implementation

Don’t assume that driver will be an instance of FireFoxDriver or InternetExplorerDriver. For example when running the integration tests on your continuous build (linux) you will receive a RemoteDriver.

It’s quite easy to create a small framework around selenium using :

LabelledParameterized : to be able to run with different browsers IE,FF,… or with different user language fr/nl/en

ScreenShotWatchMan : that takes screenshot on exception and logs the html sources. (see ./target/screenshot/*.png)


Avoid External Test Dependencies

Use Setup and Teardown

If there are are "prerequisite" tasks that need to be taken care of before your test runs, you should include a setup section in your script that executes them before the actual testing begins. For example, you may need to to log in to the application, or dismiss an introductory dialog that pops up before getting into the application functionality that you want to test.

Similarly, if there are "post requisite" tasks that need to occur, like closing the browser, logging out, or terminating the remote session, you should have a teardown section that takes care of them for you. 

Don't Hard Code Dependencies on External Accounts or Data

Development and testing environments can change significantly in the time between the writing of you test scripts and when they run, especially if you have a standard set of tests that you run as part of your overall testing cycle. For this reason, you should avoid building into your scripts any hard coded dependencies on specific accounts or data, Instead, use API requests to dynamically provide the external inputs you need for your tests. 


Don't Use Brittle Locators in Your Tests

WebDriver provides a number of locator strategies for accessing elements on a webpage. It's tempting to use complex XPath expressions like //body/div/div/*[@class="someClass"] or CSS selectors like #content .wrapper .main. While these might work when you are developing your tests, they will almost certainly break when you make unrelated refactoring changes to your HTML output.

Instead, use sensible semantics for CSS IDs and form element names, and try to restrict yourself to using these semantic identifiers. For example, in Java you could designate elements with driver.findElement(By.id("someId")); or driver.findElement(By.name("someName")); or, in the example of PHP, you could use $this->byId() or $this->byName() . This makes it much less likely that you'll inadvertently break your page by shuffling around some lines of code.

Use Environment Variables for Authentication Credentials

As a best practice, we recommend setting your Sauce Labs authentication credentials as environment variables that can be referenced from within your tests, as shown in this code example. This provides an extra layer of security for your tests, and also enables other members of your development and testing team to write tests that will authenticate against a single account.

Use Explicit Waits

There are many situations in which your test script may run ahead of the website or application you're testing, resulting in timeouts and a failing test. For example, you may have a dynamic content element that, after a user clicks on it, a loading appears for five seconds. If your script isn't written in such a way as to account for that five second load time, it may fail because the next interactive element isn't available yet. 

Use the Latest Version of Selenium Client Bindings

The Selenium Project is always working to improve the functionality and performance of its client drivers for supported languages like Java, C#, Ruby, Python, and JavaScript, so you should always be using the latest version of the driver for your particular scripting language. You can find these on the Downloads page of the SeleniumHQ website, under Selenium Client & WebDriver Language Bindings. 

Imperative v. Declarative Test Scenarios

Imperative v. declarative test scenarios is a concept that is often discussed in the context of Cucumber and Behavior Driven Development (BDD), but it is applicable to all languages and test runners. A great post by Aslak, the author of Cucumber, gives a great description of his intentions along with a number of additional links at the bottom for further reading.

Imperative testing or programming is essentially spelling out with as much detail as necessary how to accomplish something.

Declarative testing or programming is only specifying (or declaring) what needs to be accomplished.

This is seen acutely in BDD circles because the goal of BDD is to get all of the interested parties (Project, Dev, Test, Business, etc) to collaborate on the requirements of a feature before anyone begins working on the implementation. Many testers have latched on to BDD tools as glorified test runners rather than a way to actually facilitate BDD practices. This results in features that include actual code and data structures. Less problematic, but still usually missing the point, is a heavy reliance on imperative scenarios. For example: 

Given I open a browser

And I navigate to https://example.com/login

When I type in the username field bob97

And I type in the password field F1d0

And I click on Submit button

Then I should see the message Welcome Back Bob

This scenario is not focused solely on the business requirements, and actually needs to have knowledge implementation specific details in order to work. The fact that the user’s username is bob97 has nothing to do with the business requirements of the company. If BDD features are designed to represent the business logic, then they should only be changed if the business requirements change. If bob97 changed his password to 1<3MyD0g, the page location changes ,or the success message changes, this test would fail, even though the business needs are exactly the same.

A declarative example of the same functionality looks like this:

Given I am on the Login Page

When I sign in with correct credentials

Then I should see a welcome message

This is all information that the business cares about, is easier to read, and leaves it to the implementation to specify how a successful login is accomplished.

This principle can be applied to any language or test runner. Tests should largely focus on what needs to be accomplished, not the details of how it is done. They should mostly be understandable when read by non-developers. This approach goes very well with using the Page Object Pattern. Keep the business logic in the test, and put all of the information about the drivers, the element locators, the timing, etc in the Page Object.  

Use Maven to Manage Project Dependencies

Do you use use Maven as the dependency manager for your projects? If so, this article will give you some insight into how it works, along with some useful commands. You will find these especially helpful if you are using a private repository as the main repo to source the dependencies for your project. By using the dependency list generation methods described in this article, you can greatly reduce the workload needed to make dependencies available in your private repository, or locally if you intend to run your project offline.

How Does Maven Manage Dependencies?

You add dependencies for your project to your Maven configuration file (also known as the pom.xml file, for Project Object Model). As you build your project using Maven, it resolves these dependencies and downloads the dependencies to your local repository folder. This folder is usually located in your user’s home folder and is named .m2. Each dependency downloaded from the repository is a project itself, and has its own dependencies. Maven recursively resolves all of these dependencies for you, and then merges shared dependencies and downloads them. At the end of the process you end up with a list of dependencies that are needed to run your project on your local machine. For full details about how this process works, check out the Maven documentation.

How Do I Get the Dependencies for a Project?

From this brief description of how Maven dependencies work, you may notice a problem: How do you know exactly what dependencies are required for a project, and if you don’t have Internet access or are trying to run your project offline, how do you make sure you have all the dependencies you need available locally? Fortunately, Maven includes several commands that you can use to make sure you have all the dependencies and repositories set up so that your project will build and run with no errors.

First, check for version updates to your dependencies, and then update the outdated dependencies in your pom.xml file as necessary.

$ mvn versions:display-dependency-updates

Get a list of your repositories, and make sure they’re pointing to all the correct dependencies.

$ mvn dependency:list-repositories

Get a list of your plugin and project dependencies, and make sure they’re all available in your private or local repository. 

$ mvn dependency:go-offline

Syed Farjad Ali

xHBL || ISTQB certified Automation Senior SQA Engineer || Selenium || Rest Assured API || Katalon

7 年
Rizwan Jafri

CTFL, ISTQB Foundation Level Agile Tester - SSTE, Automation testing expert

7 年

Wonderful All the needed info at one place.

要查看或添加评论,请登录

mahesh patnam的更多文章

  • Best Practices for Building Test Automation Framework

    Best Practices for Building Test Automation Framework

    Test Automation – A Brief History: Most of the people had no idea about test automation frameworks at that time…

    2 条评论
  • Importance Of Robot class in selenium

    Importance Of Robot class in selenium

    In certain Selenium Automation Tests, there is a need to control keyboard or mouse to interact with OS windows like…

  • Selenium Best tips and tricks PartThree

    Selenium Best tips and tricks PartThree

    1: Best Method To Create Webdriver Instance. It’s one of the most common Selenium Webdriver coding tips which you can’t…

  • Selenium Best tips and tricks PartTwo

    Selenium Best tips and tricks PartTwo

    1. Drag and Drop The action chain generator implements the Builder pattern to create a Composite Action containing a…

社区洞察

其他会员也浏览了