API automation framework as a Ruby Gem | ‘client-api’​ Launch

client-api is an open-source library (ruby gem), which is a HTTP REST API client for testing application APIs based on the ruby’s RSpec framework that binds a complete api automation framework setup within itself.

The client-api library reduces the effort of writing bulky lines of codes with simple and painless test steps. Debugging and validations are made easy and that greatly increases the end-user productivity.

:client-api => { Ruby + API + Automation }

List of client-api features

What features does client-api contain? Let me break them down:

  • Custom Header, URL, Basic Auth, and Timeout support
  • Datatype and key-pair value validation
  • Single key-pair response validation
  • Multi key-pair response validation
  • JSON response content validation
  • JSON response schema validation
  • JSON response headers validation
  • JSON template as a body and schema
  • Support to store JSON responses of each tests for the current run
  • Logs support for debugging
  • Auto-handle SSL for http(s) schemes
Feature Blueprint [client-api v0.2.7]

Installation

Add this line to your application’s Gemfile:

gem 'client-api'

And then execute:

$ bundle

Or make a direct install:

$ gem install client-api

Import the library in your .env file

require 'client-api'

Usage outline

Add or remove the below optional configuration in the spec_helper.rb file, and make sure the values are updated that rely on your application.

ClientApi.configure do |config|
config.base_url = 'https://reqres.in'
config.headers = {'Content-Type' => 'application/json', 'Accept' => 'application/json'}
config.basic_auth = {'Username' => 'ahamilton@apigee.com', 'Password' => 'myp@ssw0rd'}
config.json_output = {'Dirname' => './output', 'Filename' => 'test'}
config.time_out = 10 # in secs
config.logger = {'Dirname' => './logs', 'Filename' => 'test', 'StoreFilesCount' => 2}

# add this snippet only if the logger is enabled
config.before(:each) do |scenario|
ClientApi::Request.new(scenario)
end
end

Initialize client-api object with custom variable and follow test steps,

api = ClientApi::Api.new

The RSpec test scenarios look like,

@api = ClientApi::Api.newit "GET request" do
@api.get('/api/users')
expect(@api.status).to eq(200)
expect(@api.code).to eq(200)
expect(@api.message).to eq('OK')
end
it "POST request" do
@api.post('/api/users', {"name": "prashanth sams"})
expect(@api.status).to eq(201)
end
it "DELETE request" do
@api.delete('/api/users/3')
expect(@api.status).to eq(204)
end
it "PUT request" do
@api.put('/api/users/2', {"data":{"email":"prashanth@mail.com","first_name":"Prashanth","last_name":"Sams"}})
expect(@api.status).to eq(200)
end
it "PATCH request" do
@api.patch('/api/users/2', {"data":{"email":"prashanth@mail.com","first_name":"Prashanth","last_name":"Sams"}})
expect(@api.status).to eq(200)
end

Validations

This modern library helps you to do different types of validations.

  1. Default validation
  2. JSON response content validation
  3. JSON response headers validation
  4. JSON response schema validation (3rd party)

Default validation

Default validation is a generic validation used by any global automation framework. ‘Datatype’ or ‘Key-pair value’ assertions are exclusive to this validation type. Please refer to the Github source for more details on the datatype and operators used in this library.

Key Features

  • Datatype validation
  • Key-pair value validation
  • Single key-pair validation
  • Multi key-pair validation

# Syntax | Model 1

validate(
api.body,
{
key: '',
value: '',
operator: '==',
type: 'string'
}
)

# Syntax | Model 2

validate(
api.body,
{
key: '',
operator: '!=',
type: 'boolean'
},
{
key: 'data->0->post->id',
operator: 'contains',
value: 40,
type: 'integer'
}
)

JSON response content validation

Content validation is the most recommended validation type for fixed or static JSON responses.

Are you bored of writing too much of assertions for the same API response unit? whew! not anymore… try validate_json(actual_json, expected_json)

Key Benefits

  • Validates each and every JSON content value including arrays and hashes
  • Minimize writing multiple assertion steps for bulk JSON response body

Other Things to Note

  • Replace null with nil in the expected JSON (whenever applicable); because, ruby doesn’t know what null is

# Syntax | Model 1

validate_json(
{
"data":
{
"id": 2,
"first_name": "Prashanth",
"last_name": "Sams",
}
},
{
"data":
{
"id": 2,
"first_name": "Prashanth",
"last_name": "Sams",
}
}
)

# Syntax | Model 2

validate_json(
api.body,
{
"data":
{
"id": 2,
"first_name": "Prashanth",
"last_name": "Sams",
"link": nil
}
}
)

JSON response headers validation

The header validation is meant to validate any key-pair values in the response headers.

# Syntax | Model 1

validate_headers(
api.response_headers,
{
key: '',
operator: '',
value: ''
}
)

# Syntax | Model 2

validate_headers(
api.response_headers,
{
key: "connection",
operator: "!=",
value: "open"
},{
key: "vary",
operator: "==",
value: "Origin, Accept-Encoding"
}
)

My Top Tips

I have put together a list of features explained with tiny snippets for a quick understanding of the library in details below.

JSON template as body

it "JSON template as body" do
api.post('/api/users', payload("./data/request/post.json"))
expect(api.status).to eq(201)
end

Add custom header

it "GET request with custom header" do
api.get('/api/users', {'Content-Type' => 'application/json', 'Accept' => 'application/json'})
expect(api.status).to eq(200)
end
it "PATCH request with custom header" do
api.patch('/api/users/2', {"data":{"email":"prashanth@mail.com","first_name":"Prashanth","last_name":"Sams"}}, {'Content-Type' => 'application/json', 'Accept' => 'application/json'})
expect(api.status).to eq(200)
end

Full url support

it "full url", :post do
api.post('https://api.enterprise.apigee.com/v1/organizations/ahamilton-eval',{},{'Authorization' => 'Basic YWhhbWlsdG9uQGFwaWdlZS5jb206bXlwYXNzdzByZAo'})
expect(api.status).to eq(403)
end

Basic Authentication support

ClientApi.configure do |config|
...
config.basic_auth = {'Username' => 'ahamilton@apigee.com', 'Password' => 'myp@ssw0rd'}
end

Custom Timeout in secs

ClientApi.configure do |config|
...
config.time_out = 10 # in secs
end

Response output as JSON template

ClientApi.configure do |config|
...
config.json_output = {'Dirname' => './output', 'Filename' => 'sample'}
end

Logs

ClientApi.configure do |config|
...
config.logger = {'Dirname' => './logs', 'Filename' => 'test', 'StoreFilesCount' => 5}

config.before(:each) do |scenario|
ClientApi::Request.new(scenario)
end
end

Source: https://rubygems.org/gems/client-api

Github: https://github.com/prashanth-sams/client-api

That is it! Thanks for reading

If you liked this article and want to be part of our brilliant team of engineers that produced it, then have a look at our latest vacancies here.

--

--