GithubHelp home page GithubHelp logo

hidroh / cucumber-api Goto Github PK

View Code? Open in Web Editor NEW
52.0 12.0 56.0 36 KB

API validator in BBD style with Cucumber

Home Page: https://rubygems.org/gems/cucumber-api

License: Apache License 2.0

Ruby 85.87% Gherkin 14.13%
cucumber bdd api json ruby ruby-gem

cucumber-api's Introduction

cucumber-api

Build Status Gem Version Dependency Status Code Climate Total Downloads

API validator in BDD style with Cucumber. cucumber-api lets one validate public APIs JSON response in blazingly fast time.

Inspired by cucumber-api-steps.

Checkout sample to see cucumber-api in action.

Installation

Add cucumber-api gem to your Gemfile:

gem 'cucumber-api'

Require cucumber-api in your Cucumber's env.rb:

require 'cucumber-api'

Configuration

Verbose logging: enable verbose logging of API calls and responses by setting cucumber_api_verbose=true in your ENV, preferably via your cucumber.yml

# config/cucumber.yml
##YAML Template
---
verbose     : cucumber_api_verbose=true

Usage

Available steps

Preparation steps

Specify your request header's Content-Type and Accept. The only supported option for Accept is application/json at the moment.

Given I send and accept JSON
Given I send "(.*?)" and accept JSON

You could also others header's information like:

Given I send and accept JSON
And I add Headers:
  | name1 | value |
  | name2 | other |  

Specify POST body

When I set JSON request body to '(.*?)'
When I set form request body to:
  | key1 | value1              |
  | key2 | {value2}            |
  | key3 | file://path-to-file |
When I set JSON request body to:
"""
{
  "key1": "jsonString",
  "key2":  1
}
"""

Or from YAML/JSON file

When I set request body from "(.*?).(yml|json)"

Example:

Given I send "www-x-form-urlencoded" and accept JSON
When I set JSON request body to '{"login": "[email protected]", "password": "password"}'
When I set form request body to:
  | login    | email@example.com     |
  | password | password              |
When I set request body from "data/json-data.json"
When I set request body from "data/form-data.yml"

Request steps

Specify query string parameters and send an HTTP request to given URL with parameters

When I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)"
When I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)" with:
  | param1 | param2 | ... |
  | value1 | value2 | ... |

Temporarily save values from the last request to use in subsequent steps in the same scenario:

When I grab "(.*?)" as "(.*?)"

Optionally, auto infer placeholder from grabbed JSON path:

# Grab and auto assign {id} as placeholder
When I grab "$..id"

The saved value can then be used to replace {placeholder} in the subsequent steps.

Example:

When I send a POST request to "http://example.com/token"
And I grab "$..request_token" as "token"
And I grab "$..access_type" as "type"
And I grab "$..id"
And I send a GET request to "http://example.com/{token}" with:
  | type            | pretty |
  | {type}          | true   |
Then the JSON response should have required key "id" of type string and value "{id}"

Assume that http://example.com/token have an element {"request_token": 1, "access_type": "full", "id": "user1"}, cucumber-api will execute the followings:

This will be handy when one needs to make a sequence of calls to authenticate/authorize API access.

Assert steps

Verify:

  • HTTP response status code
  • JSON response against a JSON schema conforming to JSON Schema Draft 4
  • Adhoc JSON response key-value type pair, where key is a JSON path
Then the response status should be "(\d+)"
Then the JSON response should follow "(.*?)"
Then the JSON response root should be (object|array)
Then the JSON response should have key "([^\"]*)"
Then the JSON response should have (required|optional) key "(.*?)" of type (numeric|string|boolean|numeric_string|object|array|any)( or null)
Then the JSON response should have (required|optional) key "(.*?)" of type (numeric|string|boolean|numeric_string|object|array|any)( or null) and value "(.*?)"

Example:

Then the response status should be "200"
Then the JSON response should follow "features/schemas/example_all.json"
Then the JSON response root should be array
Then the JSON response should have key "id"
Then the JSON response should have optional key "format" of type string or null
Then the JSON response should have required key "status" of type string and value "foobar"

Also checkout sample for real examples. Run sample with the following command:

cucumber -p verbose

Response caching

Response caching is provided for GET requests by default. This is useful when you have a Scenario Outline or multiple Scenarios that make GET requests to the same endpoint.

Only the first request to that endpoint is made, subsequent requests will use cached response. Response caching is only available for GET method.

The response cache can also be cleared if needed:

Given I clear the response cache

Dependencies

cucumber-api's People

Contributors

bartoszmajsak avatar biggianteye avatar davidlamys avatar hidroh avatar lbernardelli avatar thentenaar avatar wiggly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cucumber-api's Issues

Default header values

Headers a reset after each request, which makes sense, but in most API calls header values are always the same (like a basic auth header or content type). It would significantly DRY up tests to allow for default headers to get set that bypass the need to say "I send and accept JSON" and other header settings.

DELETE with JSON body

I'm trying to test a REST API which has a DELETE method with a JSON body to tell it what to delete. This isn't supported by the current version of cucumber-api. Are there any plans to add this? Would it break other things if a JSON body was passed?

Feature Request: Should have 'key' WITH VALUE 'value'

Feature Request.

Can we add functionality to do something like this?:

Then the response should have key “firstName” with value “Katie”

Right now we have this:

Then the response should have key “firstName”

Cookie support ?

Will be good to be able to check if response sent a cookie or not.

passing variable between scenarios

HI,

I am using your tool to test a rest API and needs to pass variable from one scenario to another.

In the first one I do a POST request to create an item and in second scenario later on I try to delete the created item.
For that I use you grab fuction in the first scenarion and try to use it in the second but does not seem to work. It seems the scope of a variable is a scenario. Do you have a work around to pass variables ?

I tried to group everything into one scenario but got errors message on headers.

And I send a POST request to "http://192.168.99.100:5252/data/application"
Then the response status should be "200"
And I grab "$.application.id" as "id"
Then I send a DELETE request to "http://192.168.99.100:5252/data/application/{id}"

<title>Error 401</title>

Unauthorized (401)

doing the same request on a different scenario work. The headers are declare by:
Given I send "x-www-form-urlencoded" and accept JSON
And I add Headers:
| Cache-Control | no-cache |
|authorization | Basic XXXXXXXXX |

Thanks for your help

Grabbed values do not work with headers

I am trying to grab a token returned from an authentication endpoint and use it as a header in subsequent requests but the grabbed field is showing as the field name in the header rather than the field value.

Here is a simplified example:

Scenario:
    # Log in and get an access token
    Given I send and accept JSON
    And I set JSON request body to:
        """
        { "email": "[email protected]", "password": "x" }
        """
    And I send a POST request to "http://api/auth/login"
    And I grab "$..access_token" as "token"

    # Try to do another request using the above token in the Authorization header
    Given I send and accept JSON
    And I add Headers:
        | Authorization | Foo {token} |
    And I send a GET request to "http://api/customer/addresses"
    ...

I would expect the Authorization header in the second request to contain the token value but it actually just contains Foo {token}.

How can I add a grabbed value as a header?

When I grab the json result as a veriable in a Scenario,how can I use it in other Scenario

When I grab the json result as a veriable in a Scenario,how can I use it in other Scenario.

Scenario: One
...
Then I grab wallet address "$..address" as "company_address"
...
Scenario: Two
...
When I set JSON request body to:
    """
      {
        "company_address": "{company_address}"
    """
When I send a POST request to "{url}"
...

But,in the Scenario Two, company_address'value is not what I want.

POST with json file

Hi,
When I send a POST request with a json file in a given path, json file is parsed as hash, that causes problem at RestClient side.

You need to modify @Body with @body.to_json , otherwise it returns 415 as response code

when 'json' @body = JSON.parse File.read(path) **@body = @body.to_json** else

Checking grabbed values does not work

Grabbed values are now being places in instance variables and are being looked up by the resolve(url) method.

The following code fails;

Feature: Property creation
  
  Scenario: Create a simple property
    Given I send and accept JSON
    When I set JSON request body to:
      """
      {
      "area_name": "Holborn",
      "address": "321 High Holborn",
      "post_code": "WC2B 5FG",
      "available": true
      }
      """
    And I send a POST request to "http://localhost:3000/properties" 
    Then the response status should be "201"
    And the JSON response should have key "id"
    And I grab "id" as "uuid"
    And the JSON response should have "id" of type string and value "{uuid}"

with the error;

    And the JSON response should have "id" of type string and value "{uuid}" # cucumber-api-0.4/lib/cucumber-api/steps.rb:183
      Did you forget to "grab" uuid? (RuntimeError)
      features/property_create.feature:17:in `And the JSON response should have "id" of type string and value "{uuid}"'

Adding some tracing statements shows that the instance (self) being used when grabbing values and that used when resolving them is different, hence no instance variables are shared.

Gem Load Error

Cucumber-Api is working fine from 'cucumber' command, but running 'rspec' or 'rails s' gives the following error:

/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler/runtime.rb:94:in rescue in block (2 levels) in require': There was an error while trying to load the gem 'cucumber-api'. (Bundler::GemRequireError) Gem Load Error is: undefined method Given' for main:Object
Backtrace for gem load error is:
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/cucumber-api-0.4/lib/cucumber-api/steps.rb:11:in <top (required)>' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in require'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in block in require' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:240:in load_dependency'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:274:in require' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/cucumber-api-0.4/lib/cucumber-api.rb:1:in <top (required)>'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler/runtime.rb:91:in require' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler/runtime.rb:91:in block (2 levels) in require'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler/runtime.rb:86:in each' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler/runtime.rb:86:in block in require'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler/runtime.rb:75:in each' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler/runtime.rb:75:in require'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/bundler-1.13.6/lib/bundler.rb:106:in require' /Users/mattlindsey/Documents/github/redeemify/config/application.rb:7:in <top (required)>'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:78:in require' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:78:in block in server'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:75:in tap' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:75:in server'
/Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/commands/commands_tasks.rb:39:in run_command!' /Users/mattlindsey/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/commands.rb:17:in <top (required)>'
bin/rails:4:in require' bin/rails:4:in

'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.