Table of Contents
If you ever had to develop a website, I’m pretty sure you 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 and it can be removed by doing some user interface testing.
With user interface testing, UI tests work in the same way a user would; they open a browser, they load a page, and: they check that the content is where it should be, they click on several items, insert data into forms, etc. just to check if the browser acts as it should.
In order to create and run those tests, here are 2 user interface testing example of tools:
User interface 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
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. And finally, the core scenario: Given, When, Then. These three keywords represent the three stages of the test:
- In the “Given” stage, we set the preconditions that this scenario will have. In our example, the preconditions were that I was a signed in user.
- In the “When” stage, 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.
- Finally, the “Then” describes 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”; that 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 organised 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 for an example of testing framework that implements the BDD syntax. Now, I will use Selenium WebDriver as an example of 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. But 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 initialise a driver for Chrome, using the ‘navigate_to’ binding to open an url and interact with the page.
Selenium offers quite an interesting variety of bindings, almost all of them very semantic, that allows us to make use of the web as if it was a mouse and a keyboard.
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:
> bundle install
> cucumber
to see this test running.
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.
I hope you enjoyed this article about user interface testing, in the next post I will provide you with a bigger example of the use of Cucumber & Selenium, the Do’s and Dont’s, and I will introduce you to the Page Object Pattern.
Author
-
Software developer with over 8 years experience working with different code languages, able to work as a FullStack Developer, with the best skills in the backend side. Passionate about new technologies, and the best software development practices involved in a DevOps culture. Enjoying mentoring teams and junior developers and I feel very comfortable with the stakeholders management-wise.
View all posts