API testing in BBD 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
:
1 2 | gem 'cucumber-api' |
Require cucumber-api
in your Cucumber’s env.rb
:
1 | <span class="pl-k">require</span> <span class="pl-s"><span class="pl-pds">'</span>cucumber-api<span class="pl-pds">'</span></span> |
Configuration
Verbose logging: enable verbose logging of API calls and responses by settingcucumber_api_verbose=true
in your ENV
, preferably via your cucumber.yml
1 2 3 4 | <span class="pl-c"># config/cucumber.yml</span> <span class="pl-c">##YAML Template</span> <span class="pl-s">-<span class="pl-s">--</span></span> <span class="pl-s"><span class="pl-ent">verbose :</span> <span class="pl-s">cucumber_api_verbose=true</span></span> |
Usage
Available steps
Preparation steps
Specify your request header’s Content-Type
and Accept
. The only supported option for Accept
isapplication/json
at the moment.
1 2 | <span class="pl-k">Given </span>I send and accept JSON <span class="pl-k">Given </span>I send <span class="pl-s">"(.*?)"</span> and accept JSON |
Specify POST body
1 2 3 4 5 | <span class="pl-k">When </span>I set JSON request body to <span class="pl-s">'(.*?)'</span> <span class="pl-k">When </span>I set form request body to: <span class="pl-k"> | <span class="pl-s1">key1</span> | <span class="pl-s1">value1</span> |</span> <span class="pl-k"> | <span class="pl-s1">key2</span> | {<span class="pl-s1">value2</span>} |</span> <span class="pl-k"> | <span class="pl-s1">key3</span> | <span class="pl-s1">file</span>://<span class="pl-s1">path</span>-<span class="pl-s1">to</span>-<span class="pl-s1">file</span> |</span> |
Or from YAML/JSON file
1 | <span class="pl-k">When </span>I set request body from <span class="pl-s">"(.*?).(yml|json)"</span> |
Example:
1 2 3 4 5 6 7 | <span class="pl-k">Given </span>I send <span class="pl-s">"www-x-form-urlencoded"</span> and accept JSON <span class="pl-k">When </span>I set JSON request body to <span class="pl-s">'{"login": "[email protected]", "password": "password"}'</span> <span class="pl-k">When </span>I set form request body to: <span class="pl-k"> | <span class="pl-s1">login</span> | <span class="pl-s1">email</span>@<span class="pl-s1">example</span>.<span class="pl-s1">com</span> |</span> <span class="pl-k"> | <span class="pl-s1">password</span> | <span class="pl-s1">password</span> |</span> <span class="pl-k">When </span>I set request body from <span class="pl-s">"data/json-data.json"</span> <span class="pl-k">When </span>I set request body from <span class="pl-s">"data/form-data.yml"</span> |
Request steps
Specify query string parameters and send an HTTP request to given URL with parameters
1 2 3 4 | <span class="pl-k">When </span>I send a (GET|POST|PATCH|PUT|DELETE) request to <span class="pl-s">"(.*?)"</span> <span class="pl-k">When </span>I send a (GET|POST|PATCH|PUT|DELETE) request to <span class="pl-s">"(.*?)"</span> with: <span class="pl-k"> | <span class="pl-s1">param1</span> | <span class="pl-s1">param2</span> | ... |</span> <span class="pl-k"> | <span class="pl-s1">value1</span> | <span class="pl-s1">value2</span> | ... |</span> |
Temporarily save values from the last request to use in the next request in the same scenario:
1 | <span class="pl-k">When </span>I grab <span class="pl-s">"(.*?)"</span> as <span class="pl-s">"(.*?)"</span> |
The saved value can then be used to replace {placeholder}
in the next request.
Example:
1 2 3 4 5 6 | <span class="pl-k">When </span>I send a POST request to <span class="pl-s">"http://example.com/token"</span> <span class="pl-k">And </span>I grab <span class="pl-s">"$..request_token"</span> as <span class="pl-s">"token"</span> <span class="pl-k">And </span>I grab <span class="pl-s">"$..access_type"</span> as <span class="pl-s">"type"</span> <span class="pl-k">And </span>I send a GET request to <span class="pl-s">"http://example.com/{token} with:</span> <span class="pl-s"> | type | pretty |</span> <span class="pl-s"> | {type} | true |</span> |
Assume that http://example.com/token have an element {"request_token": 1, "access_type": "full"}
, cucumber-api will execute the followings:
- POST http://example.com/token
- Extract the first
request_token
andaccess_type
from JSON response and save it for next request - GET http://example.com/1?type=full&pretty=true
- Clear all saved values
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
1 2 3 4 5 | <span class="pl-k">Then </span>the response status should be <span class="pl-s">"(<span class="pl-cce">\d</span>+)"</span> <span class="pl-k">Then </span>the JSON response should follow <span class="pl-s">"(.*?)"</span> <span class="pl-k">Then </span>the JSON response root should be (object|array) <span class="pl-k">Then </span>the JSON response should have key <span class="pl-s">"([^<span class="pl-cce">\"</span>]*)"</span> <span class="pl-k">Then </span>the JSON response should have (required|optional) key <span class="pl-s">"(.*?)"</span> of type (numeric|string|array|boolean|numeric_string|object|array|any)( or null) |
Example:
1 2 3 4 5 | <span class="pl-k">Then </span>the response status should be <span class="pl-s">"200"</span> <span class="pl-k">Then </span>the JSON response should follow <span class="pl-s">"features/schemas/example_all.json"</span> <span class="pl-k">Then </span>the JSON response root should be array <span class="pl-k">Then </span>the JSON response should have key <span class="pl-s">"id"</span> <span class="pl-k">Then </span>the JSON response should have optional key <span class="pl-s">"format"</span> of type string or null |
Also checkout sample for real examples. Run sample with the following command:
1 2 | 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.
Dependencies
- cucumber for BDD style specs
- jsonpath for traversal of JSON response via JSON path
- json-schema for JSON schema validation
- rest-client for HTTP REST request
Read Similar Posts