Introduction to Cucumber testing tool
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 ...
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.
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 "youremail@email.com" 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:
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.