Use Ruby’s JSON module to run simple Cucumber scenarios to test a RESTful API, DevOps style!

Step 1. Create the directory we’ll be working

$ mkdir cucumber-json
$ cd cucumber-json

Step 2. Generate the Ruby application

$ bundle init
Writing new Gemfile to /cucumber-json/Gemfile

Step 3. Set up dependencies for cucumber and rspec

$ vim Gemfile

Should look something like this

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'cucumber'
gem 'rspec'

Step 4. Install dependencies

Depending on the versions being used, you should see something similar to this.

$ bundle install
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
Using builder 3.2.3
Using bundler 2.0.1
Fetching backports 3.15.0
Fetching cucumber-tag_expressions 1.1.1
Installing cucumber-tag_expressions 1.1.1
Fetching gherkin 5.1.0
Installing backports 3.15.0
Installing gherkin 5.1.0
Fetching cucumber-expressions 6.0.1
Installing cucumber-expressions 6.0.1
Fetching cucumber-wire 0.0.1
Installing cucumber-wire 0.0.1
Using diff-lcs 1.3
Using multi_json 1.13.1
Fetching multi_test 0.1.2
Installing multi_test 0.1.2
Using rspec-support 3.8.2
Fetching cucumber-core 3.2.1
Using rspec-core 3.8.2
Using rspec-expectations 3.8.4
Using rspec-mocks 3.8.1
Using rspec 3.8.0
Installing cucumber-core 3.2.1
Fetching cucumber 3.1.2
Installing cucumber 3.1.2
Bundle complete! 2 Gemfile dependencies, 17 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

Our tree looks like this.

$ tree
.
├── Gemfile
└── Gemfile.lock

Step 5. Initialize Cucumber

$ cucumber --init
  create   features
  create   features/step_definitions
  create   features/support
  create   features/support/env.rb

Our tree is now…

$ tree
.
├── Gemfile
├── Gemfile.lock
└── features
    ├── step_definitions
    └── support
        └── env.rb

3 directories, 3 files

Step 6. Write a feature and scenario to test.

$ touch features/github.feature
$ vim features/github.feature

To keep it short, we can add a few expected JSON responses.

Feature: Test the Github API

Background:
  Given path "https://api.github.com"

Scenario: smoke test examples
  When a user requests "/"
  Then they are returned "current_user_url" => "https://api.github.com/user"
  Then they are returned "current_user_authorizations_html_url" => "https://github.com/settings/connections/applications{/client_id}"
  Then they are returned "authorizations_url" => "https://api.github.com/authorizations"
  Then they are returned "code_search_url" => "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}"
  Then they are returned "commit_search_url" => "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}"

Step 7. Run the test (use this to cheat)

$ cucumber

The output should look something like this. Cucumber before step definitions

Step 8. Create step definitions with specs.

$ touch features/step_definitions/gitub_steps.rb
$ vim features/step_definitions/gitub_steps.rb

We will use Ruby’s built-in JSON module to parse curl requests. This is our secret weapon.

Hint: copy/paste the empty test results into the step definitions file.

require 'json'

Given("path {string}") do |string|
  @path = string
end

When("a user requests {string}") do |string|
  @hash = JSON.parse(`curl #{@path}#{string}`)
end

Then("they are returned {string} => {string}") do |key, value|
  expect(@hash[key]).to eq(value)
end

Step 9. Run the test.

$ cucumber

cucumber running successfully

Step 10. Generate pretty output so the boss is happy.

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

This generates a nice HTML file for viewing.

cucumber report

The final tree

$ tree
.
├── Gemfile
├── Gemfile.lock
├── features
│   ├── github.feature
│   ├── step_definitions
│   │   └── gitub_steps.rb
│   └── support
│       └── env.rb
└── report.html

3 directories, 6 files

Of course there is a LOT more we can do with an API, this is just a quick “how to get started” demo. Hope you get some value from it.

–Brad

See more at the Github repo