Today I want to write about behavior driven development (BDD) with Cucumber and Capybara. All those things are not new, but since I changed my company I had the chance to learn new frameworks and tools. Before using the tools you need to install them :). For me the installation was kind of nasty because I am working with windows again and the installation is not so easy and comfortable as for linux or mac. The following stuff needs to be installed on your machine (windows):
- Ruby version >1.9.x http://rubyinstaller.org/
- Ruby Gems http://rubyforge.org/frs/?group_id=126
- QT4 support for windows. Follow the instructions from here
If the installation is done you should install the following gems with ‘gem.bat install GEMNAME‘
builder, bundler, bundler-unload, capybara, capybara-screenshot, capybara-webkit, childprocess, cucumber, diff-lcs, ffi, gherkin, headless, json, mime-types, mini_portile, multi_json, nokogiri, rack, rack-test, rake, rspec, rspec-core, rspec-expectations, rspec-mocks, rubygems-bundler, rubyzip, rvm, selenium-webdriver, websocket, xpath
Now you are able to create your first cucumber project. See the example project structure:
Cucumber Project Folder:
features:
step_definitions:
registerSteps.rb
loginSteps.rb
navigationSteps.rb
support:
capybara.rb
env.rb
path.rb
register.feature
login.feature
navigation.feature
The first step you should do is to create a .feature
file. For example create the login.feature
file in the features
folder and start writing your first cucumber tests with gherkin. Gherkin is the business specific language that describes how the software should behave and how cucumber should interact with the software. Gherkin has only a few easy keywords to describe the software. The first part is the feature description followed by the scenarios. A feature usually contains more scenarios for describing/ testing the feature. A scenario is like a test method and should be run independently from other scenarios. Within a scenario you define the steps that should be executed. A typical scenario has the following structure:
Feature: As a user I want be able to login to my private account
Scenario: Login with valid data
Given I am on the "loginpage"
When I enter a valid username
And I enter a valid password
Then I press the login button
Then I should be logged in
This is a really easy way to describe a valid login test. These steps could be written by product managers, customers or other stakeholders. The next step is to write step definitions so that cucumber knows what to do with the scenarios. To write these definitions you can use capybara. Capybara is able to simulate real user interaction on webpages using different rendering engines like webkit.
When cucumber executes the steps it is automatically looking for a matching step definition. Cucumber uses regular expression to match the steps.
A step definition for the login example could look like:
Given(/^I am on the "(.*?)"$/) do | pagename |
visit path_to(pagename)
end
When(/^I enter a valid username$/) do
fill_in("id_username", :with => "TestUserName")
end
And(/^I enter a valid password$/) do
fill_in("id_password", :with => "TestUserPassword")
end
Then(/^I press the login button$/) do
click_button("Login")
end
Then(/^I should be logged in$/) do
page.find("Welcome TestUserName").visible?
end
Save these steps in a ruby file loginSteps.rb in the step_definitions
folder. Hint: Cucumber does not distinguish between the keywords Given
, When
, Then
, And
or But
. Those keywords are just for better reading and understanding the scenario. You could also use an * instead of one of those words. More information about Given, When, Then can be found here.
To execute the cucumber tests you need some configuration files. One of those files is the capybara.rb
. In this file you define which render engine should be used e.g. webkit.
require 'capybara'
require 'capybara/dsl'
require 'capybara/cucumber'
require 'capybara/session'
require 'capybara-webkit'
Capybara.default_selector =:xpath
Capybara.save_and_open_page_path = 'temp/capybara'
Capybara.run_server = true
Capybara.javascript_driver = :webkit
Capybara.default_driver = :webkit
Capybara.default_wait_time = 2
The other ruby file is the paths.rb
. In this file you define the URL of the application you want to test. Additionally you can create shortcut paths to open an application URL within your step definitions (see step definition Given I am on the “loginpage”). The paths.rb
file could look like:
module NavigationHelpers
def current_domain
ENV['domain'] ? ENV['domain'] : 'www.YOURAPPLICATION.com'
end
def path_to(page_name) domain = current_domain case page_name when /home/ "http://#{domain}/" when /loginpage/ "http://#{domain}/login" else raise "Can't find mapping from "#{page_name}" to a path.n" + "Now, go and add a mapping in #{__FILE__}" end end end
World(NavigationHelpers)
In a next step you can create some hooks. Hooks can be saved in the support/env.rb
file. Cucumber provide several hooks like before
, after
, afterStep
, afterConfiguration
, to define what should happen e.g. before every scenario or step.
You can execute the cucumber tests with the following command:
cucumber.bat features/login.feature
Now you should be able to create your test suite with cucumber and capybara. The following links provide additional useful information:
- http://www.richardlawrence.info/2011/10/27/cucumber-tip-key-value-tables/
- https://github.com/cucumber/cucumber/wiki/tutorials-and-related-blog-posts
- https://github.com/cucumber/cucumber/wiki/Continuous-Integration
That’s it for today, Have Fun!