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.rbloginSteps.rbnavigationSteps.rb
support:capybara.rbenv.rbpath.rb
register.featurelogin.featurenavigation.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 inThis 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)
endWhen(/^I enter a valid username$/) do
fill_in("id_username", :with => "TestUserName")
endAnd(/^I enter a valid password$/) do
fill_in("id_password", :with => "TestUserPassword")
endThen(/^I press the login button$/) do
click_button("Login")
endThen(/^I should be logged in$/) do
page.find("Welcome TestUserName").visible?
endSave 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 = 2The 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 NavigationHelpersdef current_domainENV['domain'] ? ENV['domain'] : 'www.YOURAPPLICATION.com'enddef 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 endWorld(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!