Behavior-driven Development with Selenium WebDriver

Exclusive offer: get 50% off this eBook here
Selenium Testing Tools Cookbook

Selenium Testing Tools Cookbook — Save 50%

Over 90 recipes to build, maintain, and improve test automation with Selenium WebDriver with this book and ebook.

$26.99    $13.50
by Unmesh Gundecha | January 2013 | Open Source

Behavior-driven Development (BDD) is an agile software development practice that enhances the paradigm of Test Driven Development (TDD) and acceptance tests, and encourages the collaboration between developers, quality assurance, domain experts, and stakeholders. Behavior-driven Development was introduced by Dan North in the year 2003 in his seminal article available at http://dannorth.net/introducing-bdd/.

In this article by Unmesh Gundecha, author of Selenium Testing Tools Cookbook, we will cover:

  • Using Cucumber-JVM and Selenium WebDriver in Java for BDD

  • Using SpecFlow.NET and Selenium WebDriver in .NET for BDD

  • Using JBehave and Selenium WebDriver in Java

  • Using Capybara, Cucumber, and Selenium WebDriver in Ruby

(For more resources related to this topic, see here.)

Using Cucumber-JVM and Selenium WebDriver in Java for BDD

BDD/ATDD is becoming widely accepted practice in agile software development, and Cucumber-JVM is a mainstream tool used to implement this practice in Java. Cucumber-JVM is based on Cucumber framework, widely used in Ruby on Rails world.

Cucumber-JVM allows developers, QA, and non-technical or business participants to write features and scenarios in a plain text file using Gherkin language with minimal restrictions about grammar in a typical Given, When, and Then structure.

This feature file is then supported by a step definition file, which implements automated steps to execute the scenarios written in a feature file. Apart from testing APIs with Cucumber-JVM, we can also test UI level tests by combining Selenium WebDriver.

In this recipe, we will use Cucumber-JVM, Maven, and Selenium WebDriver for implementing tests for the fund transfer feature from an online banking application.

Getting ready

  1. Create a new Maven project named FundTransfer in Eclipse.

  2. Add the following dependencies to POM.XML:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http:// maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>FundTransfer</groupId> <artifactId>FundTransfer</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-java</artifactId> <version>1.0.14</version> <scope>test</scope> </dependency> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-junit</artifactId> <version>1.0.14</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.25.0</version> </dependency> </dependencies> </project>

How to do it...

Perform the following steps for creating BDD/ATDD tests with Cucumber-JVM:

  1. Select the FundTransfer project in Package Explorer in Eclipse. Select and right-click on src/test/resources in Package Explorer. Select New | Package from the menu to add a new package as shown in the following screenshot:

  2. Enter fundtransfer.test in the Name: textbox and click on the Finish button.

  3. Add a new file to this package. Name this file as fundtransfer.feature as shown in the following screenshot:

  4. Add the Fund Transfer feature and scenarios to this file:

    Feature: Customer Transfer's Fund As a customer, I want to transfer funds so that I can send money to my friends and family Scenario: Valid Payee Given the user is on Fund Transfer Page When he enters "Jim" as payee name And he enters "100" as amount And he Submits request for Fund Transfer Then ensure the fund transfer is complete with "$100 transferred successfully to Jim!!" message Scenario: Invalid Payee Given the user is on Fund Transfer Page When he enters "Jack" as payee name And he enters "100" as amount And he Submits request for Fund Transfer Then ensure a transaction failure message "Transfer failed!! 'Jack' is not registered in your List of Payees" is displayed Scenario: Account is overdrawn past the overdraft limit Given the user is on Fund Transfer Page When he enters "Tim" as payee name And he enters "1000000" as amount And he Submits request for Fund Transfer Then ensure a transaction failure message "Transfer failed!! account cannot be overdrawn" is displayed

  5. Select and right-click on src/test/java in Package Explorer. Select New | Package from menu to add a new Package as shown in the following screenshot:

  6. Create a class named FundTransferStepDefs in the newly-created package. Add the following code to this class:

    package fundtransfer.test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.By; import cucumber.annotation.*; import cucumber.annotation.en.*; import static org.junit.Assert.assertEquals; public class FundTransferStepDefs { protected WebDriver driver; @Before public void setUp() { driver = new ChromeDriver(); } @Given("the user is on Fund Transfer Page") public void The_user_is_on_fund_transfer_page() { driver.get("http://dl.dropbox.com/u/55228056/fundTransfer. html"); } @When("he enters \"([^\"]*)\" as payee name") public void He_enters_payee_name(String payeeName) { driver.findElement(By.id("payee")).sendKeys(payeeName); } @And("he enters \"([^\"]*)\" as amount") public void He_enters_amount(String amount) { driver.findElement(By.id("amount")).sendKeys(amount); } @And("he Submits request for Fund Transfer") public void He_submits_request_for_fund_transfer() { driver.findElement(By.id("transfer")).click(); } @Then("ensure the fund transfer is complete with \"([^\"]*)\" message") public void Ensure_the_fund_transfer_is_complete(String msg) { WebElement message = driver.findElement(By.id("message")); assertEquals(message.getText(),msg); } @Then("ensure a transaction failure message \"([^\"]*)\" is displayed") public void Ensure_a_transaction_failure_message(String msg) { WebElement message = driver.findElement(By.id("message")); assertEquals(message.getText(),msg); } @After public void tearDown() { driver.close(); } }

  7. Create a support class RunCukesTest which will define the Cucumber-JVM configurations:

    package fundtransfer.test; import cucumber.junit.Cucumber; import org.junit.runner.RunWith; @RunWith(Cucumber.class) @Cucumber.Options(format = {"pretty", "html:target/cucumber-htmlreport", "json-pretty:target/cucumber-report.json"}) public class RunCukesTest { }

  8. To run the tests in Maven life cycle select the FundTransfer project in Package Explorer. Right-click on the project name and select Run As | Maven test. Maven will execute all the tests from the project.

  9. At the end of the test, an HTML report will be generated as shown in the following screenshot. To view this report open index.html in the target\cucumber-htmlreport folder:

How it works...

Creating tests in Cucumber-JVM involves three major steps: writing a feature file, implementing automated steps using the step definition file, and creating support code as needed.

For writing features, Cucumber-JVM uses 100 percent Gherkin syntax. The feature file describes the feature and then the scenarios to test the feature:

Feature: Customer Transfer's Fund As a customer, I want to transfer funds so that I can send money to my friends and family

You can write as many scenarios as needed to test the feature in the feature file. The scenario section contains the name and steps to execute the defined scenario along with test data required to execute that scenario with the application:

Scenario: Valid Payee Given the user is on Fund Transfer Page When he enters "Jim" as payee name And he enters "100" as amount And he Submits request for Fund Transfer Then ensure the fund transfer is complete with "$100 transferred successfully to Jim!!" message

Team members use these feature files and scenarios to build and validate the system. Frameworks like Cucumber or JBehave provide an ability to automatically validate the features by allowing us to implement automated steps. For this we need to create the step definition file that maps the steps from the feature file to automation code. Step definition files implement a method for steps using special annotations. For example, in the following code, the @When annotation is used to map the step "When he enters "Jim" as payee name" from the feature file in the step definition file. When this step is to be executed by the framework, the He_enters_payee_name() method will be called by passing the data extracted using regular expressions from the step:

@When("he enters \"([^\"]*)\" as payee name") public void He_enters_payee_name(String payeeName) { driver.findElement(By.id("payee")).sendKeys(payeeName); }

In this method, the WebDriver code is written to locate the payee name textbox and enter the name value using the sendKeys() method.

The step definition file acts like a template for all the steps from the feature file while scenarios can use a mix and match of the steps based on the test conditions.

A helper class RunCukesTest is defined to provide Cucumber-JVM configurations such as how to run the features and steps with JUnit, report format, and location, shown as follows:

@RunWith(Cucumber.class) @Cucumber.Options(format = {"pretty", "html:target/cucumber-htmlreport", "json-pretty:target/cucumber-report.json"}) public class RunCukesTest { }

There's more…

In this example, step definition methods are calling Selenium WebDriver methods directly. However, a layer of abstraction can be created using the Page object where a separate class is defined with the definition of all the elements from FundTransferPage:

import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.CacheLookup; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class FundTransferPage { @FindBy(id = "payee") @CacheLookup public WebElement payeeField; @FindBy(id = "amount") public WebElement amountField; @FindBy(id = "transfer") public WebElement transferButton; @FindBy(id = "message") public WebElement messageLabel; public FundTransferPage(WebDriver driver) { if(!"Online Fund Transfers".equals(driver.getTitle())) throw new IllegalStateException("This is not Fund Transfer Page"); PageFactory.initElements(driver, this); } }

Using SpecFlow.NET and Selenium WebDriver in .NET for BDD

We saw how to use Selenium WebDriver with Cucumber-JVM for BDD/ATDD. Now let's try using a similar combination in .NET using SpecFlow.NET. We can implement BDD in .NET using the SpecFlow.NET and Selenium WebDriver .NET bindings.

SpecFlow.NET is inspired by Cucumber and uses the same Gherkin language for writing specs. In this recipe, we will implement tests for the Fund Transfer feature using SpecFlow.NET. We will also use the Page objects for FundTransferPage in this recipe.

Getting ready

This recipe is created with SpecFlow.NET Version 1.9.0 and Microsoft Visual Studio Professional 2012.

  1. Download and install SpecFlow from Visual Studio Gallery http://visualstudiogallery.msdn.microsoft.com/9915524d-7fb0-43c3-bb3c-a8a14fbd40ee.

  2. Download and install NUnit Test Adapter from http://visualstudiogallery.msdn.microsoft.com/9915524d-7fb0-43c3-bb3c-a8a14fbd40ee.

This will install the project template and other support files for SpecFlow.NET in Visual Studio 2012.

How to do it...

You will find the Fund Transfer feature in any online banking application where users can transfer funds to a registered payee who could be a family member or a friend. Let's test this feature using SpecFlow.NET by performing the following steps:

  1. Launch Microsoft Visual Studio.

  2. In Visual Studio create a new project by going to File | New | Project. Select Visual C# Class Library Project. Name the project FundTransfer.specs as shown in the following screenshot:

  3. Next, add SpecFlow.NET, WebDriver, and NUnit using NuGet. Right-click on the FundTransfer.specs solution in Solution Explorer and select Manage NuGet Packages... as shown in the following screenshot:

  4. On the FundTransfer.specs - Manage NuGet Packages dialog box, select Online, and search for SpecFlow packages. The search will result with the following suggestions:

  5. Select SpecFlow.NUnit from the list and click on Install button. NuGet will download and install SpecFlow.NUnit and any other package dependencies to the solution. This will take a while.

  6. Next, search for the WebDriver package on the FundTransfer.specs - Manage NuGet Packages dialog box.

  7. Select Selenium WebDriver and Selenium WebDriver Support Classes from the list and click on the Install button.

  8. Close the FundTransfer.specs - Manage NuGet Packages dialog box.

Creating a spec file

The steps for creating a spec file are as follows:

  1. Right-click on the FundTransfer.specs solution in Solution Explorer. Select Add | New Item.

  2. On the Add New Item – FundTransfer.specs dialog box, select SpecFlow Feature File and enter FundTransfer.feature in the Name: textbox. Click Add button as shown in the following screenshot:

  3. In the Editor window, your will see the FundTransfer.feature tab.

  4. By default, SpecFlow will add a dummy feature in the feature file. Replace the content of this file with the following feature and scenarios:

    Feature: Customer Transfer's Fund As a customer, I want to transfer funds so that I can send money to my friends and family Scenario: Valid Payee Given the user is on Fund Transfer Page When he enters "Jim" as payee name And he enters "100" as amount And he Submits request for Fund Transfer Then ensure the fund transfer is complete with "$100 transferred successfully to Jim!!" message Scenario: Invalid Payee Given the user is on Fund Transfer Page When he enters "Jack" as payee name And he enters "100" as amount And he Submits request for Fund Transfer Then ensure a transaction failure message "Transfer failed!! 'Jack' is not registered in your List of Payees" is displayed Scenario: Account is overdrawn past the overdraft limit Given the user is on Fund Transfer Page When he enters "Tim" as payee name And he enters "1000000" as amount And he Submits request for Fund Transfer Then ensure a transaction failure message "Transfer failed!! account cannot be overdrawn" is displayed

Creating a step definition file

The steps for creating a step definition file are as follows:

  1. To add a step definition file, right-click on the FundTransfer.sepcs solution in Solution Explorer. Select Add | New Item.

  2. On the Add New Item - FundTransfer.specs dialog box, select SpecFlow Step Definition File and enter FundTransferStepDefs.cs in the Name: textbox.

  3. Click on Add button. A new C# class will be added with dummy steps. Replace the content of this file with the following code:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using TechTalk.SpecFlow; using NUnit.Framework; using OpenQA.Selenium; namespace FundTransfer.specs { [Binding] public class FundTransferStepDefs { FundsTransferPage _ftPage = new FundsTransferPage(Environment.Driver); [Given(@"the user is on Fund Transfer Page")] public void GivenUserIsOnFundTransferPage() { Environment.Driver.Navigate().GoToUrl("http:// localhost:64895/Default.aspx"); } [When(@"he enters ""(.*)"" as payee name")] public void WhenUserEneteredIntoThePayeeNameField(string payeeName) { _ftPage.payeeNameField.SendKeys(payeeName); } [When(@"he enters ""(.*)"" as amount")] public void WhenUserEneteredIntoTheAmountField(string amount) { _ftPage.amountField.SendKeys(amount); } [When(@"he enters ""(.*)"" as amount above his limit")] public void WhenUserEneteredIntoTheAmountFieldAboveLimit (string amount) { _ftPage.amountField.SendKeys(amount); } [When(@"he Submits request for Fund Transfer")] public void WhenUserPressTransferButton() { _ftPage.transferButton.Click(); } [Then(@"ensure the fund transfer is complete with ""(.*)"" message")] public void ThenFundTransferIsComplete(string message) { Assert.AreEqual(message, _ftPage.messageLabel.Text); } [Then(@"ensure a transaction failure message ""(.*)"" is displayed")] public void ThenFundTransferIsFailed(string message) { Assert.AreEqual(message, _ftPage.messageLabel.Text); } } }

Defining a Page object and a helper class

The steps for defining a Page object and a helper class are as follows:

  1. Define a Page object for the Fund Transfer Page by adding a new C# class file. Name this class FundTransferPage. Copy the following code to this class:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenQA.Selenium; using OpenQA.Selenium.Support.PageObjects; namespace FundTransfer.specs { class FundTransferPage { public FundTransferPage(IWebDriver driver) { PageFactory.InitElements(driver, this); } [FindsBy(How = How.Id, Using = "payee")] public IWebElement payeeNameField { get; set; } [FindsBy(How = How.Id, Using = "amount")] public IWebElement amountField { get; set; } [FindsBy(How = How.Id, Using = "transfer")] public IWebElement transferButton { get; set; } [FindsBy(How = How.Id, Using = "message")] public IWebElement messageLabel { get; set; } } }

  2. We need a helper class that will provide an instance of WebDriver and perform clean up activity at the end. Name this class Environment and copy the following code to this class:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using TechTalk.SpecFlow; namespace FundTransfer.specs { [Binding] public class Environment { private static ChromeDriver driver; public static IWebDriver Driver { get { return driver ?? (driver = new ChromeDriver(@"C:\ChromeDriver")); } } [AfterTestRun] public static void AfterTestRun() { Driver.Close(); Driver.Quit(); driver = null; } } }

  3. Build the solution.

Running tests

The steps for running tests are as follows:

  1. Open the Test Explorer window by clicking the Test Explorer option on Test | Windows on Main Menu.

  2. It will display the three scenarios listed in the feature file as shown in the following screenshot:

  3. Click on Run All to test the feature as shown in the following screenshot:

How it works...

SpecFlow.NET first needs the feature files for the features we will be testing. SpecFlow.NET supports the Gherkin language for writing features.

In the step definition file, we create a method for each step written in a feature file using the Given, When, and Then attributes. These methods can also take the parameter values specified in the steps using the arguments. Following is an example where we are entering the name of the payee:

[When(@"he enters ""(.*)"" as payee name")] public void WhenUserEneteredIntoThePayeeNameField(string payeeName) { _ftPage.payeeNameField.SendKeys(payeeName); }

In this example, we are automating the "When he enters "Jim" as payee name" step. We used the When attribute and created a method: WhenUserEneteredIntoThePayeeNameField. This method will need the value of the payee name embedded in the step which is extracted using the regular expression by the SpecFlow.NET. Inside the method, we are using an instance of the FundTransferPage class and calling its payeeNameField member's SendKeysl() method, passing the name of the payee extracted from the step. Using the Page object helps in abstracting locator and page details from the step definition files, making it more manageable and easy to maintain.

SpecFlow.NET automatically generates the NUnit test code when the project is built. Using the Visual Studio Test Explorer and NUnit Test Adaptor for Visual Studio, these tests are executed and the features are validated.

Selenium Testing Tools Cookbook Over 90 recipes to build, maintain, and improve test automation with Selenium WebDriver with this book and ebook.
Published: November 2012
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Using JBehave and Selenium WebDriver in Java

JBehave is another famous framework for BDD/ATDD in Java. Similar to Cucumber-JVM, JBehave allows the writing of features as stories in the Gherkin language. Steps from the scenarios are later implemented in a step definition file.

In this recipe, we will explore using JBehave and Selenium WebDriver together for creating tests on a BMI calculator application.

Getting ready

You need to download and set up the JBehave Web extension, which is based on JBehave Core. It provides support for web-related access or functionality, including Selenium/WebDriver support.

The latest release of JBehave Web Distribution is available in JBehave's repository at Codehaus Nexus. You need to download the latest jbehave-web-distribution from https://nexus.codehaus.org/content/repositories/releases/org/jbehave/web/jbehave-web-distribution/.

Download the complete zip archive from the previously mentioned location. For this recipe, jbehave-web-distribution-3.5-bin.zip is used.

After downloading the JBehave Web, unzip the contents of this file on your machine. Locate the lib subdirectory; this directory contains all JAR files needed to create and run the following examples.

How to do it...

  1. Create a new Java project and add all the JAR files to build a path from the lib subdirectory from the JBehave Web directory extracted earlier. This will add JBehave and Selenium support to the project. Also, add JUnit Library to this project.

  2. We now need to prepare a story file, which will contain acceptance criteria for a user story written in the Given, When and Then structure. We will create a simple story file for the BMI Calculator Application; let's call this Bmi.story. Create this using the with following steps, in the source folder of your project.

    Narrative: I should be able to Calculate my Body Mass Index Scenario: I should see my BMI after entering Height and Weight When I open BMI Calculator Home Page When I enter height as '181' When I enter weight as '80' When I click on the Calculate button Then I should see bmi as '24.4' and category as 'Normal'

  3. Next, we need to map steps from this story and create a step definition class. We will create a plain Java class that will extend the StoryBase class, which we will create shortly. For each step we will create a method with the @When and @Then annotations from the JBehave framework:

    import junit.framework.Assert; import org.jbehave.core.annotations.Then; import org.jbehave.core.annotations.When; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; public class Bmi extends StoryBase { @When("I open BMI Calculator Home Page") public void IOpen() { driver.get("http://dl.dropbox.com/u/55228056/ bmicalculator.html"); } @When("I enter height as '$height'") public void IEnterHeight(String height) { WebElement heightCMS = driver.findElement(By. id("heightCMS")); heightCMS.sendKeys(height); } @When("I enter weight as '$weight'") public void IEnterWeight(String weight) { WebElement weightKg = driver.findElement(By. id("weightKg")); weightKg.sendKeys(weight); } @When("I click on the Calculate button") public void IClickOnTheButton() { WebElement button = driver.findElement(By. id("Calculate")); button.click(); } @Then("I should see bmi as '$bmi_exp' and category as '$bmi_category_exp'") public void IShouldBmiAndCategory(String bmi_exp, String bmi_category_exp) { WebElement bmi = driver.findElement(By.id("bmi")); Assert.assertEquals(bmi_exp, bmi.getAttribute("value")); WebElement bmi_category = driver.findElement(By. id("bmi_category")); Assert.assertEquals(bmi_category_exp, bmi_category. getAttribute("value")); driver.quit(); } }

  4. Finally, we will create a Configuration class that will be used by the step definition classes. In this class, we set up necessary configurations to execute the stories using JBehave and Selenium. We will name this class StoryBase and this will be extended from the JUnitStory class in the JBehave framework:

    import java.util.List; import org.jbehave.core.configuration.Configuration; import org.jbehave.core.configuration.MostUsefulConfiguration; import org.jbehave.core.io.LoadFromClasspath; import org.jbehave.core.junit.JUnitStory; import org.jbehave.core.reporters.Format; import org.jbehave.core.reporters.StoryReporterBuilder; import org.jbehave.core.steps.InstanceStepsFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public abstract class StoryBase extends JUnitStory { protected final static WebDriver driver = new FirefoxDriver(); @Override public Configuration configuration() { return new MostUsefulConfiguration() .useStoryLoader(new LoadFromClasspath(this. getClass().getClassLoader())) .useStoryReporterBuilder( new StoryReporterBuilder() .withDefaultFormats() .withFormats(Format.HTML, Format.CONSOLE) .withRelativeDirectory ("jbehave-report") ); } @Override public List candidateSteps() { return new InstanceStepsFactory(configuration(), this).createCandidateSteps(); } }

How it works...

For creating tests in JBehave, we will need to first implement stories as the .story file using the Given, When, and Then structures. We need to add the Narrative section to describe the purpose of the story and the Scenario section, which contains the actual steps. We also pass the required test data from these steps:

Narrative: I should be able to Calculate my Body Mass Index Scenario: I should see my BMI after entering Height and Weight When I open BMI Calculator Home Page When I enter height as '181' ... Then I should see bmi as '24.4' and category as 'Normal'

Next, we map these steps using a step definition class. This class extends the StoryBase class, which will provide the necessary support to run the story in the JBehave framework, including an instance of WebDriver:

public class Bmi extends StoryBase

For each step, we use an annotation and implement a method to run that step. For example, for the step When I enter height as '181' we have defined the IEnterHeight() method as follows:

@When("I enter height as '$height'") public void IEnterHeight(String height) { WebElement heightCMS = driver.findElement(By. id("heightCMS")); heightCMS.sendKeys(height); }

We used the @When annotation here and also used '$height' for extracting the value mentioned in the .story file and passed this value to the IEnterHeight() method. In this method, we created an instance of WebElement for the height textbox and called its sendKeys() method, passing the value.

Along with a story file and a step definition class, a Configuration class needs to be created, which will be based on the JUnitStory class from the JBehave framework:

public abstract class StoryBase extends JUnitStory

The StoryBase class provides an instance of WebDriver to all the story or step definition classes:

protected final static WebDriver driver = new FirefoxDriver();

It also provides other configuration information, like the location of the story files and report settings, and format the JBehave framework. In this case, the .story files will be located using the path of the story or step definition classes:

@Override public Configuration configuration() { return new MostUsefulConfiguration() .useStoryLoader(new LoadFromClasspath(this.getClass(). getClassLoader())) .useStoryReporterBuilder( new StoryReporterBuilder() .withDefaultFormats() .withFormats(Format.HTML, Format.CONSOLE) .withRelativeDirectory("jbehave-report") ); }

We used the JUnitStory class so that we can execute these tests with JUnit Test Runner. At the end of the execution, JBehave generates an HTML report with a detailed status of the stories executed, stories passed, or failed.

Using Capybara, Cucumber, and Selenium WebDriver in Ruby

Capybara is an acceptance test framework for web applications in Ruby. It integrates with Ruby-based BDD frameworks such as Cucumber and RSpec along with Selenium WebDriver for web testing capabilities. Capybara is widely used in testing Rails applications.

In this recipe, we will see how to use Capybara, Cucumber, and Selenium to test BMI Calculator application.

Getting ready

  1. You need to install Capybara Gem by using the following command:

    gem install capybara

  2. Additionally, you also need to install Cucumber and RSpec Gem on a fresh Ruby installation, as follows:

    gem install cucumber gem install rspec

How to do it...

In Capybara, we need to create a features file for the stories under test. These stories are written in Gherkin language with the Given, When, and Then structures in Cucumber format. Perform the following steps to create a feature and step definition file with Capybara:

  1. Create a plain text file named BmiCalculate.feature, as follows:

    Feature: BMI Calculator has a Calculate Function Scenario: Calculate BMI Given I am on BMI Calculator When I fill in the following: | heightCMS | 181 | | weightKg | 80 | When I press "Calculate" Then I should see following: | bmi | 24.4 | | bmi_category | Normal |

  2. Next, we need to create a step file for the feature file created earlier. This file maps each step from the feature file to a Capybara function to work on UI. Create a Ruby file with the following code and name it BmiCalculate.rb::

    Given /^I am on BMI Calculator$/ do visit "http://dl.dropbox.com/u/55228056/bmicalculator.html" end When /^I fill in the following:$/ do |table| table.rows_hash.each {|field, value| fill_in field, :with => value } end When /^I press "([^"]*)"$/ do |button| click_button(button) end Then /^I should see following:$/ do |table| table.rows_hash.each {|field, value| find_field(field). value.should == value } end

  3. Finally, we need to create a configuration file that provides required support to run the features with Cucumber. Create a new file with the following code and name it env.rb:

    require 'capybara' require 'capybara/cucumber' require 'selenium/webdriver' Capybara.default_driver = :selenium Capybara.register_driver :selenium do |app| Capybara::Selenium::Driver.new(app, :browser => :firefox) end

How it works...

We need to copy all of these files together in a directory named features and use the cucumber command as follows:

cucumber

Since we are using Cucumber along with Capybara, it first needs feature files written in plain English. Cucumber allows defining feature files to enter data in web forms using a table-like format. In the following example, we have a step which will populate the height and weight fields in the BMI Calculator application:

When I fill in the following: | heightCMS | 181 | | weightKg | 80 |

The steps from a feature file are then mapped to Capybara commands using a step file written in Ruby. In the following example, the previously mentioned table format is mapped to a Capybara command, fill_in:

When /^I fill in the following:$/ do |table| table.rows_hash.each {|field, value| fill_in field, :with => value } end

To run these features with Cucumber we need a configuration file that will tell Capybara to use Selenium as a driver:

require 'capybara' require 'capybara/cucumber' require 'selenium/webdriver' Capybara.default_driver = :selenium Capybara.register_driver :selenium do |app| Capybara::Selenium::Driver.new(app, :browser => :firefox) end

When Cucumber runs the features, a default report is generated in the following format:

Summary

This article introduced Behavior-driven Development with Selenium WebDriver using tools such as Cucumber-JVM, JBehave for Java, SpecFlow.NET for .NET, and Capybara for Ruby.

Resources for Article :


Further resources on this subject:


Selenium Testing Tools Cookbook Over 90 recipes to build, maintain, and improve test automation with Selenium WebDriver with this book and ebook.
Published: November 2012
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Unmesh Gundecha

Unmesh Gundecha has a Master’s Degree in Software Engineering and around 10 years of experience in Software Development and Testing. Unmesh has architected functional test automation projects using industry standard, in-house and custom test automation frameworks along with leading commercial and open source test automation tools. Presently he is working as Test Architect with a multinational company in Pune, India.

He is also author of Selenium Testing Tools Cookbook published by Packt in November 2012.

Books From Packt


 NetBeans Platform 6.9 Developer's Guide
NetBeans Platform 6.9 Developer's Guide

 NetBeans IDE 7 Cookbook
NetBeans IDE 7 Cookbook

 Python Testing Cookbook
Python Testing Cookbook

 Selenium 1.0 Testing Tools: Beginner’s Guide
Selenium 1.0 Testing Tools: Beginner’s Guide

 Selenium 2 Testing Tools: Beginner’s Guide
Selenium 2 Testing Tools: Beginner’s Guide

 Jenkins Continuous Integration Cookbook
Jenkins Continuous Integration Cookbook

 Android Application Testing Guide
Android Application Testing Guide

 Advanced Penetration Testing for Highly-Secured Environments: The Ultimate Security Guide
Advanced Penetration Testing for Highly-Secured Environments: The Ultimate Security Guide


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
H
L
N
z
t
n
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software