Methods & Tools Software Development Magazine

Software Development Magazine - Project Management, Programming, Software Testing

 

Turnip - Gherkin extension for RSpec

Wataru Miyaguni, @gongoZ, http://gongo.hatenablog.com/, Jonas Nicklas, @jonicklas

Turnip is an open source Ruby gem that provides a platform for acceptance tests by combining Gherkin, the language defined by the Cucumber Behavior-Driven Development (BDD) tool to express requirements, and RSpec, an open source BDD tool for Ruby programmers. Turnip aims to solve some of the issues faced when writing specifications with Cucumber. This presentation describes the basic use of Turnip and compares it with Cucumber. If you are interested in Turnip, please visit the official site to check out all its features.

Web Site: https://github.com/jnicklas/turnip
Version tested: 2.1.0
System requirements: Ruby 2.1 or later, RSpec 3.3 and 3.4
License & Pricing: The MIT License
Support: Issue tracker at
https://github.com/jnicklas/turnip/issues,
Mailing list at https://groups.google.com/forum/#!forum/ruby-turnip

Software testing

Software testing is an important activity used to manage and investigate information about the quality of products and services. Software can be tested at various levels: unit, integration, acceptance, etc. Libraries that support software testing at each level have been released for many programming languages. JUnit (Java) and RSpec (Ruby) are examples of libraries that support unit testing. Acceptance testing is a process for verifying whether the software meets its specifications. Cucumber is one of the most famous tool that supports specifically acceptance testing. It used also the Gherkin language that has become a standard used by other open source BDD tools like Behat or SpecFlow.

Writing Acceptance Tests with Cucumber

Cucumber tests are divided among two files that together form the entire test: the "feature file" and the "step file". The feature file describes the scenarios that are written in a plain text format with the Gherkin language. The step file describes how those Gherkin files are executed and are written in various programming languages.

Please refer to the official Cucumber site and the introduction page for more information about environment construction and execution procedures. As mentioned above, you can create an "executable specification" by combining the specifications written in natural language and the steps written in a programming language.

Cucumber supports various programming languages (Java, Ruby, etc.). Therefore "executable specification" and automated testing frameworks such as JUnit and RSpec can be combined. As a result, you can realize "software testing using an executable specification" and you can prevent the obsolescence of specifications at the same time.

Cucumber Problems

Cucumber supports various programming languages and is also very popular as an acceptance testing framewor, but there are however some issues when you write Cucumber specifications.

1. Step definition must be regular expression.

# feature file
Scenario: Login
  When I login to service as tom
  Then Successful login

# step file
When(/I login to service as (\w+)/) do |name|
  # ...
end

Then(/Successful login/) do
  # This step does not need to be regular expression
end

2. Steps are always global

If you create steps with the same name in a different context (situation), it would be redundant.

# feature file
Scenario: To move in hell
  When I take a walk in hell

Scenario: To move in heaven
  When I take a walk in heaven

# step file
When(/I take a walk in hell/) do
  @hitpoint -= 1
end

When(/I take a walk in heaven/) do
  @hitpoint += 1
end

# Other way
When(/I take a walk in (\w+)/) do |place|
  case place
  when 'hell'
    @hitpoint -= 1
  when 'heaven'
    @hitpoint += 1
  end
end

Turnip

If you are facing the problems described above, you may be able to solve them using the Turnip gem.

Turnip is a Gherkin extension for RSpec that

  • Parses the Gherkin format text
  • Provides a DSL for step definition built on Ruby paradigms.
  • Executes a Ruby block in the RSpec environment
  • In the same way than Cucumber, Turnip can be an executable specification with a feature file and is used as an automated test.

1. Installation

Use the gem command:

$ gem install turnip

2. Setting

Require the step definition files in spec_helper.rb :

require 'turnip/rspec'

Dir.glob("spec/steps/**/*_steps.rb") { |f| load f, true }

3. Writing scenario

Write scenarios in Gherkin format:

# ex. spec/features/attack_monster.feature

Feature: Attacking a monster

  Background:
    Given there is a monster

  Scenario: attack the monster
    When I attack it
    Then it should die

4. Step definition

Use the step DSL.

# ex. spec/steps/attack_monster_steps.rb

step "there is a monster" do
  @monster = 1
end

step "I attack it" do
  @monster -= 1
end

step "it should die" do
  @monster.should eq(0)
end

5. Execution

Run the feature files with the rspec command:

$ rspec -fd spec/features/attack_monster.feature

Attacking a monster
  attack the monster
    Given there is a monster -> When I attack it -> Then it should die

Finished in 0.00235 seconds (files took 0.15661 seconds to load)
1 example, 0 failures

Solving Cucumber Problems

The following example explains how Turnip attempts to solve problems with Cucumber.

1. Placeholder in step definition

Turnip uses a placeholder instead of regular expression in step definitions:

# feature file
Scenario: Login as admin
  When I login to service as admin
  Then Successful login

Scenario: Login as John
  When I login to service as "John Doe"
  Then Successful login

# step file
step 'I login to service as :name' do |name|
  # name = 'admin' or 'John Doe'
end

step 'Successful login' do
  # ...
end

A word or string that is enclosed in single quote or double quote will be recognized by Turnip as a placeholder parameter.

2. Scoped steps

In Turnip, a step can be defined in any module. As a result, it can be defined with the same name.

module AtHellSteps
  step 'I take a walk' do
    @hitpoint -= 1
  end
end

module AtHeavenSteps
  step 'I take a walk' do
    @hitpoint += 1
  end
end

You can choose the defined steps within each module in the feature file.

Setting:

RSpec.configure do |config|
  config.include AtHellSteps, :hell => true
  config.include AtHeavenSteps, :heaven => true
end

In the feature file:

@hell
Scenario: To walk the hell
  When I take a walk

@heaven

Scenario: To walk the heaven
  When I take a walk

To choose the steps of a module included in this way, you specify the tag beginning with @. Additionally, Turnip provides syntax sugar to define scoped steps.

steps_for :hell do
  step 'I take a walk' do
    @hitpoint -= 1
  end
end

steps_for :heaven do
  step 'I take a walk' do
    @hitpoint += 1
  end
end

Conclusion

Turnip works like Cucumber as it is a framework that primarily supports acceptance testing. Although Turnip is not as feature-rich as Cucumber, it is simple and powerful, which makes acceptance testing easier and more accessible.

References

What is a gem? - RubyGems Guides: http://guides.rubygems.org/what-is-a-gem/

Gherkin Cucumber Wiki: https://github.com/cucumber/cucumber/wiki/Gherkin

RSpec: Behavior Driven Development for Ruby: http://rspec.info/

Software testing on Wikipedia: https://en.wikipedia.org/wiki/Software_testing

Acceptance testing on Wikipedia: https://en.wikipedia.org/wiki/Acceptance_testing

Cucumber: https://cucumber.io/

Cucumber Documentation: https://cucumber.io/docs

The Ruby Toolbox - Acceptance Test Frameworks:
https://www.ruby-toolbox.com/categories/Acceptance_Test_Frameworks

Bundler: The best way to manage a Ruby application's gems: http://bundler.io/gemfile.html


More Software Testing Knowledge

Functional Testing Tools

Software Testing Magazine

Software Testing Videos & Tutorials


Click here to view the complete list of tools reviews

This article was originally published in the Summer 2016 issue of Methods & Tools

SpiraTeam Agile ALM


Software Testing Magazine

Scrum Expert