Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

A Look at User Interface Testing

DZone's Guide to

A Look at User Interface Testing

UI tests work like a user; they open a browser, load a page, click on several items, insert data into forms, etc. just to check if the browser acts as it should.

· DevOps Zone
Free Resource

Learn more about how CareerBuilder was able to resolve customer issues 5x faster by using Scalyr, the fastest log management tool on the market. 

If you've ever developed a website, you probably spent hours checking that the website looks correct and that the user flow through the pages is not broken after several changes. Trying the same flow over and over is a waste of time. This can be removed by doing some user interface testing.

UI tests work in the same way a user would; they open a browser, they load a page, they click on several items, they insert data into forms, etc. just to check if the browser acts as it should.

Here are two examples of UI testing tools.

Cucumber

 This user interface testing framework allows us to easily write understandable tests using an implementation of the BDD syntax known as Gherkin.

Writing a test with Gherkin is like writing down a feature. In fact, every feature to test should be a file .feature, with this structure: 

Feature: Visit my profile
In order to know what information my profile contains
As a registered user
I want to check my profile

Scenario: Visiting my profile as a signed in user
Given I am a user and I have signed in 
When I go to ‘my profile’
Then I should see my information

The feature is just a brief description of what the test is going to check. In this case, the test just wants to check if the profile page is available. To test this feature, we created one scenario, but we could have done more. “Visiting my profile page without signing in before” could be an example of a test that should check that you can’t access any profile page without signing in before. Finally, there's the core scenario: given, when, then. These three keywords represent the three stages of the test:

  1. Given: We set the preconditions that this scenario will have. In our example, the preconditions were that I was a signed in user.
  2. When: We describe the trigger, the action that we are going to test. This action should be something quite general as “sign in” or “create a project” or “go to my profile” without revealing the implementation because it can change and the test shouldn’t.
  3. Then: We describe the outcome. This is the step where the assertions will be made in order to check that everything looks as you expected.

There are more keywords. “Background” sets a precondition for all the scenarios (“and” and “but,” for example). The key idea is that internally “given,” “when,” “then,” “and,” and “but” are (and work) exactly the same. They are nothing more than aliases that help us write understandable tests.

Every step that we write will have an implementation and this implementation will be stored in a step_definitions directory. Some people create a step definition file for each feature, but that’s an error. The step definitions should be unique and organized in files according to their domain, a file for the “given” steps related to signing in, out, and up, for example. In that way, we remove the duplication.

The examples of step definitions will be given below with a brief example using Selenium.

For more information related to Gherkin, I strongly recommend you read the Cucumber wiki.

Selenium WebDriver

Earlier, I used Cucumber as an example of a testing framework that implements the BDD syntax. Now, I will use Selenium WebDriver as an example of an open-source web browser automation library.

Selenium allows us to use several WebDriver plugins to interact with the browser of our choice. The main use of Selenium in our environment is to launch and interact with a real browser, allowing us to write tests interacting with the web page, clicking, checking text, hovering, dragging, filling forms, etc.

In our example, we will use the Ruby version of Selenium with the Chrome implementation of WebDriver, ChromeDriver. There are versions for Java, Ruby, Python, C#, and Node.js, as well as drivers for a really huge list of browsers, including Chrome, Firefox, Opera, PhantomJS, Microsoft edge, etc.

The standard use of Selenium would be, for example:

require “selenium-webdriver”

driver = Selenium::WebDriver.for :chrome
driver.navigate.to “http://google.com”

element = driver.find_element(:name, ‘q’)
element.send_keys “Hello WebDriver!”
element.submit
 
puts driver.title
 
driver.quit

In this example, we can see how we initialize a driver for Chrome using the navigate_to binding to open a URL and interact with the page.

Selenium offers quite an interesting variety of bindings, almost all of them very semantic, that allow us to make use of the web as if it was a mouse and a keyboard. For more information, please visit this page about Ruby bindings.

Finally, an example of a UI test using Cucumber, Selenium, and RSpec (just for the assertions) could be:

|
|_ features
|    |
|    |
|    |_ example.feature:
|    |
|    |            Feature: Checking the title of google.com
|    |
|    |                Scenario: Google.com title should be ‘Google’
|    |                    When I navigate to google.com
|    |                    Then the browser displays a website with the title Google
|    |                    And the website title is not Yahoo
|    |
|    |_ step_definitions
|    |        |
|    |        |
|    |        |
|    |        |_ steps.rb
|    |
|    |              When “I navigate to $url” do |url|
|    |                @browser.navigate.to “http://#{url}”
|    |              end
|    |
|    |              Then “the browser displays a website with the title $title” do |title|
|    |                expect(@browser.title).to eq title
|    |              end
|    |
|    |              And “the website title is not $title” do |title|
|    |                expect(@browser.title).to_not eq title
|    |              end
|    |
|    |
|    |
|    |_ support
|          |
|          |
|          |
|          |_ env.rb
|
|                require ‘selenium/webdriver’
|
|                browser = Selenium::WebDriver.for :chrome
|
|                Before do |scenario|
|                    @browser = browser
|                end
|
|                at_exit do
|                    browser.quit
|                end
|
|
|
|
|_ Gemfile
 
       source ‘https://rubygems.org’
 
       ruby ‘2.1.9’
 
       gem ‘selenium-webdriver’, ‘2.53.0’
 
       gem ‘cucumber’, ‘2.3’
 
       gem ‘rspec’, ‘3.4’

With Ruby 2.1.9 installed, you should all be able to do this to see this test running:

> bundle install
> cucumber

Some of you might ask yourselves: What is this support/env.rb? Well, this is a configuration file that Cucumber allows us to have in order to initialize, in this example, the Selenium WebDriver before every scenario and to exit the browser after we are done.

Follow this link for more about UI testing.

Thanks for reading!

Find out more about how Scalyr built a proprietary database that does not use text indexing for their log management tool.

Topics:
ui testing ,cucumber ,selenium ,webdriver ,devops ,software testing

Published at DZone with permission of Rafael Ruiz Giner. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}