+1

Introduction to Cucumber testing tool

68747470733a2f2f63756b65732e696e666f2f696d616765732f637563756d6265722e706e67.png

In this article, I'm going to talk about Cucumber which is a tool for writing an Automated Acceptance Tests written in a behavior-driven development style. A Cucumber enable developer to see how their system behave in the hand of their user. So developer has a chance for fixing the problem before their system deliver to the real users. So let's get start.

Init the Cucumber's project

Cucumber has implemented in many languages. However in this article demonstration, I'm going to use a Cucumber which implemented in ruby langunage. By creating a file and name it Gemfile in this file we add some gems which needed in the project.

  • cucumber
  • selenium-webdriver: a brwoser automation libralry.
source 'https://rubygems.org'

gem 'cucumber'
gem 'selenium-webdriver'

and then run command bundle install. Then initialize cucumber working directory by run command:

cucumber --init

It will create some folder and file:

features
features/step_definitions
features/support
features/support/env.rb

And let's test our cucumber by running the command.

cucumber

it should display:

0 scenarios
0 steps
0m0.000s

What is the file and folder about?

  • feature: is the place where QA can write down the story of how users interact with our web site.
  • features/step_definitions: is a place where developer translate the user story into code, so when we run our automation test, the marchine can understand and perform as what we are expected.
  • feature/support && feature/support/env.rb: this place can be use to write some supporting code for use in step_definitions folder. Generally, we write some supporting environment configuration in here.

How cucumber works

When you run command cucumber, it will read the .feature files and check for all scanarios and prepare to test. In each scenario, it has a list steps for cucumber to walk through. However, cucumber cannot understand the text in feature file unless those text is written follow some basic syntax rules which called Gherkin.

Meanwhile, the file in step_definitions has been created which it has map to each step in .feature file.

During running test on each scenario, the code in step_definitions which match to step in scenario has been call, and it will convert into command and execute a brwoser automation libralry selenium-webdriver to interact with the system. It will process on each step in the scenario. If any step in a scenario raise an error, it will mark the scenario as fail and jump to the next one. If all step in a scenario has not raise any errors, it will mark as pass and move to next scenario.

Cucumber_Stack-e1401854870208.png

Let's try

Let's test with our Viblo site. And here the user story:

#feature/viblo.feature
Feature: Search Viblo Site
As a friend of Rathanak
I heard he talk about a site which sharing IT knowledge name Viblo.
I want to check it out. However, I forget the url of the site, so I want search in google.
And I hope I can find the site and explore some of Rathanak's awesome articles.

Scenario: Search viblo site in google
When I go to "google" homepage
Then I should see page title "Google"
Then I fill keyword "Viblo" in "google" search field
And  I click on search button
Then I should see Viblo site in the first top result of google search
And  I take a screenshot "google_result_page"

Scenario: Search article in viblo
When I go to "viblo" homepage
Then I should see page title "Viblo"
Then I click sign in
And  I fill email "[email protected]" and password "1234567890"
And  I click login
Then I click on search icon
And  I fill keyword "rathanak" in "viblo" search field
Then I press enter key
Then I should see Rathanak's articles
And  I take a screenshot "viblo_result_page"

then let's write ruby code for those step:

#feature/step_definitions/viblo_step.rb
When(/^I go to "([^"]*)" homepage$/) do |site_name|
  @browser.open(site_name)
end

Then(/^I should see page title "([^"]*)"$/) do |page_title|
  expect(@browser.page_title).to include page_title
end

Then(/^I fill keyword "([^"]*)" in search field$/) do |keyword|
  @browser.fill_search_keyword(keyword)
end

Then(/^I fill keyword "([^"]*)" in "([^"]*)" search field$/) do |keyword, site_name|
  @browser.fill_search_keyword(keyword, site_name)
end

Then(/^I take a screenshot "([^"]*)"$/) do |file_name|
  @browser.save_screen file_name
end

Then 'I click sign in' do
  @browser.pop_up_sign_in_form
end

Then(/^I fill email "([^"]*)" and password "([^"]*)"$/) do |email, password|
  @browser.fill_login_form(email, password)
end

Then 'I click login' do
  @browser.submit_login
end

Then 'I click on search button' do
  @browser.click_search
end

Then 'I click on search icon'  do
  @browser.search_icon_click
end

Then 'I press enter key' do
  @browser.press_enter_on_search_field
end

Then 'I should see Viblo site in the first top result of google search' do
  expect(@browser.get_first_result).to eq 'https://viblo.asia/'
end

Then "I should see Rathanak's articles" do
  expect(@browser.article_author_of_search_result).to include('Rathanak')
end

to make our code easy to manage, we'll create class for handling the logic of code in feature/step_definitions/viblo_step.rb

#feature/step_definitions/page_objects/viblo_page_object.rb
require 'uri'

class VibloPageObject
  attr_accessor :browser
  SITE_URL = {
    google: 'https://www.google.com',
    viblo: 'https://viblo.asia'
  }
  def initialize
    @browser = Selenium::WebDriver.for :firefox
  end

  def open(site_name)
    @browser.navigate.to SITE_URL[site_name.to_sym]
  end

  def page_title
    @browser.title
  end

  def fill_search_keyword(keyword, site_name)
    sleep 10
    if site_name == 'google'
      @browser.find_element(:name, 'q').send_keys(:backspace, keyword)
    else
      @browser.find_element(:id, 'search-box').send_keys(:backspace, keyword)
    end
  end

  def click_search
    @browser.find_element(:name, 'btnG').click
  end

  def get_first_result
    sleep 5
    @browser.find_elements(:class_name, '_Rm').first.text
  end

  def pop_up_sign_in_form
    @browser.find_elements(:class, 'btn-login')[1].click
  end

  def fill_login_form(email, password)
    @browser.find_element(:name, 'username').send_keys(:backspace, email)
    @browser.find_element(:name, 'password').send_keys(:backspace, password)
  end

  def submit_login
    @browser.find_elements(:class, 'btn-submit-login')[0].click
  end

  def search_icon_click
    sleep 10
    @browser.find_element(:class, 'search-icon').click
  end

  def press_enter_on_search_field
    @browser.find_element(:id, 'search-box').submit
  end

  def article_author_of_search_result
    browser.find_elements(:class, 'author')[0].text
  end

  def save_screen filename
    sleep 1
    @browser.save_screenshot("reports/screenshots/#{filename}.png")
  end

  def quit
    @browser.quit
  end
end

finally in support folder:

#feature/support/env.rb
require 'selenium-webdriver'
require './features/step_definitions/page_objects/viblo_page_object.rb'

Before do |scenario|
  @browser = VibloPageObject.new
end

After do |sceario|
  @browser.quit
end

Now let run:

cucumber

Then here the result and screenshot:

Screen Shot 2016-09-25 at 11.51.12 PM.png

viblo_result_page.png

Resource

  • soure code
  • cucumber web site
  • Book: The cucmber book. Behaviour-Driven Development for Testers and Developers. by Matt Wynne and Aslak Hellesoy.

Final words

With the explaination and sample code above, I hope you see the awesomeness of cucumber which might help you to find some bugs before you publish your product to the cloud. And you will have a better feeling everytime you ship your prodect.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.