Back to Resources

Blog

Posted February 18, 2014

Getting Started with Selenium - Chapter 3: Writing Your First Selenium Test

quote

This post is the third in a series of “Getting Started with Selenium Testing” posts from Dave Haeffner, a noted expert on Selenium and automated testing, and a frequent contributor to the Sauce blog and Selenium community. This series is for those who are brand new to test automation with Selenium and a new chapter will be posted every Tuesday (eight chapters in all).

Writing Your First Selenium Test

Fundamentally, Selenium works with two pieces of information -- the element on a page you want to use and what you want to do with it. This one-two punch will be repeated over and over until you achieve the outcome you want in your application -- at which point you will perform an assertion to confirm that the result is what you intended. Let's take logging in to a website as an example. With Selenium you would: 1. Visit the main page of a site 2. Find the login button and click it 3. Find the login form's username field and input text 4. Find the login form's password field and input text 5. Find the login form and click it Selenium is able to find and interact with elements on a page by way of various locator strategies. The list includes Class, CSS, ID, Link Text, Name, Partial Link Text, Tag Name, and XPath. While each serves a purpose, you only need to know a few to start writing effective tests.

How To Find Locators

The simplest way to find locators is to inspect the elements on a page. The best way to do this is from within your web browser. Fortunately, popular browsers come pre-loaded with development tools that make this simple to accomplish. When viewing the page, right-click on the element you want to interact with and click Inspect Element. This will bring up a small window with all of the HTML for the page but zoomed into your highlighted selection. From here you can see if there are unique or descriptive attributes you can work with.

How To Find Quality Elements

Your focus with picking an effective element should be on finding something that is uniquedescriptive, and unlikely to change. Ripe candidates for this are id and class attributes. Whereas copy (e.g., text, or the text of a link) is less ideal since it is more apt to change. This may not hold true for when you make assertions, but it's a good goal to strive for. If the elements you are attempting to work with don't have unique id and class attributes directly on them, look at the element that houses them (a.k.a. the parent element). Oftentimes the parent element has a unique locator that you can use to start with and drill down into the element you want to use (with CSS selectors). And if you can't find any unique elements, have a conversation with your development team letting them know what you are trying to accomplish. It's not hard for them to add helpful, semantic markup to make test automation easier, especially when they know the use case you are trying to automate. The alternative can be a lengthy, painful process which will probably yield working test code -- but it will be brittle and hard to maintain.

Steps To Writing a Selenium Test

There are five parts to writing a Selenium test: 1. Find the elements you want to use 2. Write a test with Selenium actions that use these elements 3. Figure out what to assert 4. Write the assertion and verify it 5. Double-check the assertion by forcing it to fail As part of writing your Selenium test, you will also need to create and destroy a browser instance. This is something that we will pull out of our tests in a future lesson, but it's worth knowing about up front. Let's take our login example from above and step through the test writing process.

An Example

The best way to find the Selenium actions for your specific language is to look at the available language binding wiki pages (RubyPython,JavaScript) or the Selenium HQ getting started documentation for WebDriver. For this example, I'll be using the Ruby programming language, RSpec (an open-source testing framework written in Ruby), and the-internet (an open-source example application I built).

1. Find the elements you want to use

Let's use the login example on the-internet). Here's the markup from the page.

html

Username

Password

Login

Note the unique elements on the form. The username input field has a unique id, as does the password input field. The submit button doesn't, but the parent element (form) does. So instead of clicking the submit button, we will have to submit the form instead. Let's put these elements to use in our first test (or 'spec' as it's called in RSpec).

2. Write a test with Selenium actions that use these elements

# filename: login_spec.rb

require 'selenium-webdriver'

describe 'Login' do

before(:each) do @driver = Selenium::WebDriver.for :firefox end

after(:each) do @driver.quit end

it 'succeeded' do @driver.get 'http://the-internet.herokuapp.com/login' @driver.find_element(id: 'username').send_keys('tomsmith') @driver.find_element(id: 'password').send_keys('SuperSecretPassword!') @driver.find_element(id: 'login').submit end

end

If we run this (e.g., rspec login_spec.rb from the command-line), it will run and pass. But there's one thing missing - an assertion. In order to find an element to make an assertion against, we need to see what the markup is after submitting the login form.

3. Figure out what to assert

Here is the markup that renders on the page after submitting the login form.

You logged into a secure area! x

Secure Area

After logging in, there looks to be a couple of things we can key off of for our assertion. There's the flash message class (most appealing), the logout button (appealing), or the copy from the h2 or the flash message (least appealing). Since the flash message class name is descriptive, denotes success, and is less likely to change than the copy, let's go with that.

4. Write the assertion and verify it

# filename: login_spec.rb

require 'selenium-webdriver'

describe 'Login' do

before(:each) do @driver = Selenium::WebDriver.for :firefox end

after(:each) do @driver.quit end

it 'successful' do @driver.get 'http://the-internet.herokuapp.com/login' @driver.find_element(id: 'username').send_keys('username') @driver.find_element(id: 'password').send_keys('password') @driver.find_element(id: 'login').submit @driver.find_element(css: '.flash.success').displayed?.should be_true end

end

5. Double-check the assertion by forcing it to fail

Now when we run this test (rspec login_spec.rb from the command-line) it will pass just like before, but now there is an assertion which should catch a failure if something is amiss. Just to make certain that this test is doing what we think it should, let's change the assertion to force a failure and run it again. A simple fudging of the locator will suffice.

@driver.find_element(css: '.flash.successasdf').displayed?.should be_true

Dave is the author of Elemental Selenium (a free, once weekly Selenium tip newsletter that is read by hundreds of testing professionals) as well as a new book, The Selenium Guidebook. He is also the creator and maintainer of ChemistryKit (an open-source Selenium framework). He has helped numerous companies successfully implement automated acceptance testing; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is a founder and co-organizer of the Selenium Hangout and has spoken at numerous conferences and meetups about acceptance testing.

Published:
Feb 18, 2014
Topics
Share this post
Copy Share Link
© 2023 Sauce Labs Inc., all rights reserved. SAUCE and SAUCE LABS are registered trademarks owned by Sauce Labs Inc. in the United States, EU, and may be registered in other jurisdictions.