API Testing & BDD

API Testing is a nice way to conduct end to end test on your application by communicating with another modules. You can read more about it here

When it comes to Behaviour Driven Development [BDD], API testing become more interesting. I am having great fun experimenting with Cucumber while reading Cucumber Book by Matt Wynne & Aslak Hellesoy. I already tried API Testing with Behat by following Keith Loy ‘s blog ‘Testing Rest API with Behat’ which you can read here.

In this short, tutorial, we will see in-process API Testing with Cucumber and Rack Test. We have assumed that Cucumber and Application sits in the same Ruby process. We will be dealing with simple API which stores and returns name of sports and players.

Start with Feature File

We will create simple web Service by using Sinatra and JSON which has /sports route and returns data in JSON format. Lets Create Project and within that project we will create ‘sports_list.feature’

Feature: Sports
In order to know about different sports
As a sport fan
I want list of some sports
Scenario: List of the sports
Given the system knows about the following sports::
| name | player |
| Cricket | Sachin Tendulkar |
| Tennis | Andy Murray |
| FootBall | David Beckham |
When the client requests GET /sports
Then response should be "200"
And the JSON response should be an array with 3 "name" elements
And response should be JSON:
"""
[
{"name": "Cricket", "player": "Sachin Tendulkar"},
{"name": "Tennis", "player": "Andy Murray"},
{"name": "FootBall", "player": "David Beckham"}
]
"""

In here, we are storing some sports and players, then make GET request /sports which should return 200 response. We are also checking number of elements and response body.

Now we will install necessary Gems. Create ‘Gemfile’ with following gems

Shashi-MacBook-Pro:REST-Cucumber-RackTest user$ cucumber
/Users/user/.rvm/gems/ruby-1.9.3-p194/gems/bundler-1.3.4/lib/bundler/runtime.rb:216: warning: Insecure world writable dir /Users/user in PATH, mode 040777
Feature: Sports
In order to know about different sports
As a sport fan
I want list of some sports
Scenario: List of the sports # features/sports_list.feature:6
Given the system knows about the following sports:: # features/sports_list.feature:8
| name | player |
| Cricket | Sachin Tendulkar |
| Tennis | Andy Murray |
| FootBall | David Beckham |
When the client requests GET /sports # features/sports_list.feature:13
Then response should be "200" # features/sports_list.feature:14
And the JSON response should be an array with 3 "name" elements # features/sports_list.feature:15
And response should be JSON: # features/sports_list.feature:16
"""
[
{"name": "Cricket", "player": "Sachin Tendulkar"},
{"name": "Tennis", "player": "Andy Murray"},
{"name": "FootBall", "player": "David Beckham"}
]
"""
1 scenario (1 undefined)
5 steps (5 undefined)
0m0.018s
You can implement step definitions for undefined steps with these snippets:
Given /^the system knows about the following sports::$/ do |table|
# table is a Cucumber::Ast::Table
pending # express the regexp above with the code you wish you had
end
When /^the client requests GET \/sports$/ do
pending # express the regexp above with the code you wish you had
end
Then /^response should be "([^"]*)"$/ do |arg1|
pending # express the regexp above with the code you wish you had
end
Then /^the JSON response should be an array with (\d+) "([^"]*)" elements$/ do |arg1, arg2|
pending # express the regexp above with the code you wish you had
end
Then /^response should be JSON:$/ do |string|
pending # express the regexp above with the code you wish you had
end

In order to make them pass, we need to

Create Simple Web service which returns JSON

Organize our Project Code with Step Definitions & Support directory

Implement Step Definitions to make them pass

Create a Project Structure by creating files and directory which will look like this :

GitHub

We have source code available on the GitHub in the repository ‘REST-Cucumber-RackTest‘. You can clone source code and execute following commands to see all the scenarios passing: