How to make Api Automation Testing with Cucumber Ruby and Httparty

Fransiskus Andika Setiawan
6 min readFeb 5, 2021

--

Photo by Annie Spratt on Unsplash

Scroll down to see tutorial, but I recommend you read all this article to increase your knowledge. Thankyou! 🤘

Cucumber

Cucumber is a tool that supports Behaviour Driven Development(BDD). BDD is about discovery, collaboration and examples. Cucumber reads executable specifications written in plain text and validates that the software does what those specifications say. The specifications consists of multiple examples, or scenarios. Example:

Scenario: Get Token Client Credentials
Given client with basic auth username:"user" and password:"pass"
When client sends a POST request to "/auth/token" with body:
"""
{
"grant_type": "client_credentials"
}
"""
Then the response status should be "200"
Then the response body should be match with json schema "schema"
Scenario: Get Content
When client sends a GET request to "<path>"
Then the response status should be "200"
When client collects data from response with json path "data.id" as "id"
Then client sends a GET request to "path/{id}"
Then the response status should be "200"
Then the response body should be match with json schema
"<schema>"
Examples:
| endpoint | schema |
| /banks |/schema-data |
| /jobs |/schema-data |

Each scenario is a list of steps for Cucumber to work through. Cucumber verifies that the software conforms with the specification and generates a report indicating ✅ success or ❌ failure for each scenario.

Each scenario has these three ingredients:

  • Given (Context)
  • When (Action)
  • Then (Outcomes)
  • Examples (Formulas Data Test)

In order for Cucumber to understand the scenarios, they must follow some basic syntax rules, called Gherkin.

Gherkin

What is Gherkin?

Gherkin is a set of grammar rules that makes plain text structured enough for Cucumber to understand. The scenario above is written in Gherkin.

Gherkin serves multiple purposes:

  • Unambiguous executable specification
  • Automated testing using Cucumber
  • Document how the system actually behaves

The Cucumber grammar exists in different flavours for many spoken languages so that your team can use the keywords in your own language.

Gherkin documents are stored in .feature text files and are typically versioned in source control alongside the software.

See the Gherkin reference for more details.

Scenario

The scenario just tells Cucumber that we will describe an example it can run. Then you see the lines starting with Given, When, and Then.

Example :

@service-name @squad-name @positive
Feature: GET Master Data
Background: Authorization
Given client logged in using client_credentials with client_id:"client_id"

Scenario: Client GET content master data by id
When client sends a GET request to "<endpoint>"
Then the response status should be "200"
When client collects data from response with json path "data.items[0].id" as "id"
Then client sends a GET request to "<endpoint>/{id}"
Then the response status should be "200"
Then the response body should be match with json schema
"<schema>"
Examples:
| endpoint | schema |
| /banks | /schema-data |
| /jobs | /schema-data |

@service-name → @tagname is used to generate tags in each feature and scenario.

Background → Background allows you to add some context to the scenarios that follow it. It can contain one or more Given steps, which are run before each scenario, but after before hooks. A Backgorund is placed before first Scenario/Example, at the same level of indentations.

Feature → Feature name

Scenario → Scenario Name

Given → Given is the context of the scenario. We put the system in a certain state, ready for scenario to unfold.

When → When is an action. Something that happens to the system that will cause something else to happen: result.

Then → Then is the result. This is behavior we expect from the system when this action occurs in this context.

And → Using And, But you could make the example more fluidy structured by replacing the successive Given’s, When’s or Then’s with And’s and But’s

Example:

Example: Multiple Givens   
Given one thing
And another thing
And yet another thing
When I open my eyes
Then I should see something But I shouldn't see something else

Examples → Examples is formula data test

Ruby

What is Ruby?

A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.

Step Definitions

What is Step Definitions?

Step definitions connect Gherkin steps to programming code. A step definition carries out the action that should be performed by the step. So step definitions hard-wire the specification to the implementation.

Step definitions

Step definitions can be written in many programming languages. Here is an example using ruby:

When(/^client sends a (GET|POST|PUT|DELETE|PATCH) request to "(.*)"(?: with body:)?$/) do |method, path, *args|
body = args.shift
body_json = body ? JSON.parse(body) : nil
path = APIHelper.resolve_variable(self, endpoint)
url = "base_url/#{path}"
@response = HTTParty.send(
method.downcase,
url,
body: body_json,
headers: @headers,
)
end

Httparty

Http Request using Httparty.

Other Tools Recommendations

Folder Structure

Folder Structure
  • Directory feature file → scenarios/api/<service-name>/<scenario-name>.feature
    In this directory we can create feature file based on the service name.
  • Directory step_definitions file → step_definitions/api/api.rb
    In this directory for general step_definitions file
  • step_definitions/api/<service-name>/<file>.rb
    In this directory we can create step definitions file based on the service name.
  • Directory JSON schema → support/api/<service-name>/schemas/<file>.json
    In this directory we can create JSON schema file based on the service name.

Install Ruby

Install rvm

Make sure you have following required packages installed:

  • curl
  • gpg2

Install curl:

brew install curl

Install gpg2:

brew install gnupg2

And then run:

curl -sSL https://get.rvm.io | bash -s stable

Install Code Editor VSCode

example : https://code.visualstudio.com/

Install ruby

rvm install ruby-2.7.0

Install bundler

gem install bundler

Generate Cucumber Project

cucumber --init

Create Gemfile

source "https://rubygems.org"
group :test do
gem "jsonpath"
gem "json-schema"
gem "test-unit"
gem "dotenv"
gem "rspec"
gem "httparty"
gem "cucumber"
gem "json"
gem "json-schema-rspec"
gem "json_matchers"
gem "pry-byebug"
end

Bundle Install → Install all dependencies on Gemfile

bundle install

Create Feature File → scenarios/api/<service-name>/<scenario-name>.feature

@get-token
Feature: Token
Scenario: Get Token Password Credentials
Given client with basic auth username:"user" and password:"pass"
When client sends a POST request to "/token" with body:
"""
{
"grant_type": "grant_type",
"username": "user",
"password": "password",
"roleId": 1
}
"""
Then the response status should be "200"
Then the response body should be match with json schema "/schema"

Create Step Definition File → step_definitions/api/<service-name>/<file>.rb

// Require Needed, you can set in file support/env.rb
require "json"
require "jsonpath"
require "json-schema"
require "test-unit"
require "test/unit/assertions"
require "minitest"
require "dotenv/load"
require "base64"
require "httparty"
require "rspec"
require "cucumber"
require "json_matchers/rspec"
require "json-schema-rspec"
require "pry"
include Test::Unit::Assertions// This for generate basic auth
def generate(username, password)
basic_auth = Base64.encode64("#{username}:#{password}").delete("\n")
return basic_auth
end
Given(/^client with basic auth username:"(.*)" and password:"(.*)"$/) do |username, password|
@headers = {
authorization: "Basic #{generate(username, password)}",
}
end
When(/^client sends a (GET|POST|PUT|DELETE|PATCH) request to "(.*)"(?: with body:)?$/) do |method, path, *args|
body = args.shift
url = "base_url/#{path}"
@response = HTTParty.send(
method.downcase,
url,
body: body,
headers: @headers,
)
end
Then(/^the response status should be "(\d+)"$/) do |code|
assert_equal(code, @response.code, "Status Code Not #{code}")
end
Then(/^the response body should be match with json schema "(.*)"/) do |schema|
expect(@response.body).to match_json_schema(schema)
end

In Other cases you can read Documentation of Httparty.

Run Test

cd dir/your-dir-api-testcucumber

Run test by @tag → cucumber --tag @tag

Run test by file → cucumber feature/scenarios/api/<dir>/<file>.feature

Genarate Report

cucumber -f pretty -f html -o report.html

Any Question? touch me

--

--