window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() BDD ON RAILS - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2016-08-19
Software Development

BDD ON RAILS

Michal Krezelewski

Today’s programmers use more and more agile practices in their everyday work. Even projects following standard software development life cycle can benefit from adapting them. Automatic testing and TDD brought more confidence to our work, facilitated implementing modifications to existing features and often lead us to better code design. But now it’s not enough. We have to push the benefits from tests to the limits and BDD allows that.BDD builds on top of TDD and adds to its practices a lot of value. It brings ubiquitous language to the project, allows for better communication between client and developers. It offers a lot for project managers and leaders, but also makes life of a developer a lot easier. Following BDD principles gives us clear requirements, tests are easier to understand and they can serve as documentation. BDD shifts focus of testing subjects and gives us confidence that we test what we should be testing – behaviour.

If you use TDD, starting with BDD will be easy – it’s basically a set of best practices for it. BDD has a set of simple rules, which tell how to write specs and what to test. Specifications are divided into three parts: Given (setting up test conditions), When (invoking action on subject) and Then (assertions). Tests should have descriptive names and existing test frameworks allow for using methods and assertions that are similar to natural language – all of which combined gives us tests that are readable by both technical and non-technical users. Good naming conventions prove useful during regression tests.

BDD comes also with set of guidelines for test subjects. In contrast to TDD it shifts focus from testing implementation to testing behaviour – and using that leads to better design and gives more flexibility when change has to be introduced. Specs should be like a written and executable client requirements – the high level ones should act as acceptance tests. The goal is to write tests in a way that needs changing them only when requirements change. Using BDD gives us confidence that we are testing what really needs to be covered and it is a more pragmatic approach than TDD.

If you want to see BDD in action, we recommend Ruby. It’s a powerful and fun to use language and it has an excellent BDD toolset.

Cucumber

Cucumber is the most popular framework for BDD in Ruby. It introduces special language, called Gherkin, in which you will write your tests. In contrast to RSpec, features described in Gherkin are plain text, not code, and as such can – and should – be understood by anyone, most notably the client.

Cucumber feature looks like this (example taken from Cucumber wiki):

 Feature: Some terse yet descriptive text of what is desired
    Textual description of the business value of this feature
    Business rules that govern the scope of the feature
    Any additional information that will make the feature easier to understand

  Scenario: Some determinable business situation
    Given some precondition
    And some other precondition
    When some action by the actor
    And some other action
    And yet another action
    Then some testable outcome is achieved
    And something else we can check happens too

  Scenario: A different situation
    ...

Features will be described later in detail.

Using Cucumber in Ruby on Rails

Installation

First step to use Cucumber in your project is installing it. Just add these two gems to your Gemfile:

group :test do
  gem 'cucumber-rails', :require => false
  gem 'database_cleaner'
end

Bundle them by running bundle install, and generate Cucumber scripts and directories with the following command:

rails generate cucumber:install

This will create config/cucumber.yml, script/cucumber and features/ directory, which will contain .feature files, as well as step definitions and supporting files. To run your features, use a new rake command:

rake cucumber

Features

Let’s take closer look at features. A feature is something your application has or does – for example periodically sends newsletter or allows user to share their photos publicly. One feature consists of multiple scenarios, which describes how this feature works in different contexts.

To demonstrate basic usage of Cucumber in Rails, we’ll write a feature from scratch. This example feature will be the first one we’ll write in the application, which will be shown in the incoming second part of this article. This application will allow User to create Items and Shops (Shops sell Items) and then create Shopping Lists.

In the simplest version, after compiling Shopping List, the application will show in which Shops the Items that the User wants are the cheapest.

First, create a new file named create_item.feature in the features/ directory. At the top of a .feature file there is a Feature keyword, followed by a short description of it. For example:

Feature: Creating Items

In the following lines you can write a business goal which will implement this feature. Since Cucumber ignores text written before the first Scenario, it’s not necessary to write anything, but it’s definitely a good idea.

   In order to easily create Shopping Lists with Items sold in nearby Shops
   As a User
   I want to add Items to the system

In the snippet, you can see a quite popular pattern above with which you can describe business goals. It consists of three parts: why is the feature necessary, who wants it, and what is it. Of course, you don’t have to follow this format, but be sure to include answers to these three questions in your description.

Scenarios

Next, we write some scenarios. Each scenario begins with the keyword “Scenario” and contains multiple steps.

    Scenario: creating unique item
      Given there is a "Milk" Item
      When I go to the main page
      And I create "Bread" Item
      Then I see "Bread" on the Item list 

So, if somebody created Item named Milk, then creating Bread is possible and results in the appearance of Bread on the Item list. We shouldn’t test for creating record in database, since this fact has no real value for the customer.

Scenario’s steps use three main keywords:

  • Given, for supplying context to the scenario
  • When, for describing actions
  • Then, for describing results

It’s important to note that Cucumber ignores the keyword step it starts with and matches only the later part. Thus, you can start your steps with “And” wherever it feels natural. The only rule for choosing the right keyword is that the Scenario must be easily understood.

Step definitions

Running Cucumber now produces this output:

[...]
Feature: Creating Items
  In order to easily create Shopping Lists with Items sold in nearby Shops
  As a User
  I want to add Items to the system

  Scenario: creating unique item   # features/create_item.feature:6
    Given there is a "Milk" Item   # features/create_item.feature:7
      Undefined step: "there is a "Milk" Item" (Cucumber::Undefined)
[...]

This is because Cucumber doesn’t know what we mean when we say “there is a Milk Item”. To add some meaning to your steps you need to define them in step_definitions directory.

A recommended way to organize your step definitions is to divide them by the domain. For example, most of the steps we’ve created, belong to Item domain. Thus, we should create a file named step_definitions/item_steps.rb and place the following code there:

Given "there is a "$name" Item" do |name|
  Fabricate :item, name: name
end

When "I create "$name" Item" do |name|
  within "#new_item" do
    fill_in "Name", with: name
    click_on "Create"
  end
end

Then "I see "$name" on the Item list" do |name|
  within ".items" do
    expect(page).to have_content name
  end
end

The steps definitions will usually be based on Capybara. If you’re not familiar with Capybara, be sure to check out links at the end of this article.

There is one more step that needs definition and it doesn’t really fit within Item steps. You could put it in main_page_steps.rb:

When "I go to the main page" do
  visit root_path
end

Conclusion

This is a very simple story for a very simple feature. Its purpose was to demonstrate core concepts of BDD as they are used in Cucumber. Writing good stories requires a bit more though. As a developer, you will need to change your mindset completely – forget about implementation and focus on business goals instead. Cucumber makes this transition easier with its clever use of plain text stories.

Sources, inspirations and interesting reads:

  • https://github.com/cucumber/cucumber/wiki/Cucumber-Backgrounder
  • https://github.com/jnicklas/capybara
  • https://blog.engineyard.com/2009/15-expert-tips-for-using-cucumber
  • http://blog.codeship.com/cucumber-best-practices/
  • http://www.elabs.se/blog/15-you-re-cuking-it-wrong
  • https://github.com/strongqa/howitzer/wiki/Cucumber-Best-Practices

Related articles

Software Development

Build Future-Proof Web Apps: Insights from The Codest’s Expert Team

Discover how The Codest excels in creating scalable, interactive web applications with cutting-edge technologies, delivering seamless user experiences across all platforms. Learn how our expertise drives digital transformation and business...

THECODEST
Software Development

Top 10 Latvia-Based Software Development Companies

Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.

thecodest
Enterprise & Scaleups Solutions

Java Software Development Essentials: A Guide to Outsourcing Successfully

Explore this essential guide on successfully outsourcing Java software development to enhance efficiency, access expertise, and drive project success with The Codest.

thecodest
Software Development

The Ultimate Guide to Outsourcing in Poland

The surge in outsourcing in Poland is driven by economic, educational, and technological advancements, fostering IT growth and a business-friendly climate.

TheCodest
Enterprise & Scaleups Solutions

The Complete Guide to IT Audit Tools and Techniques

IT audits ensure secure, efficient, and compliant systems. Learn more about their importance by reading the full article.

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish