Just API tester and nothing more.
The main objective of the module is testing APIs of web services. It is particularly suitable for REST architecture applications.
Suppose, you already have a project with configured garden environment (more info here).
Now you need to add plus.garden.api as a dependency in your garden/package.json
:
"dependencies": {
/* ... */
"plus.garden.api": "~0.0.1",
/* ... */
}
And run npm install
npm install
Or just add and install the dependency automatically via npm:
$ cd garden
$ npm install --save plus.garden.api
Now register the installed module in garden/container.js
:
module.exports = function (container) {
//...
container.register('ApiModule', require('plus.garden.api'));
//...
}
And add the registered module to garden's "world"
// garden/DIR_WITH_YOUR_TESTS/support/world.js
var World = function World(callback) {
this.api = garden.get('ApiTester');
}
That's it. Your garden is ready to use the api tester.
You write API tests in the same BDD style as usual for you in garden.js:
- Write test scenarios (more info here);
- Add missing definitions of steps where you use
plus.garden.api
; - Run tests.
Api tester includes two main components: HTTP/REST browserless client and tester that checks a response by assertions.
Let's look at an example of a common scenario and try to add a step definition using plus.garden.api
# demo/get.feature
Feature: Make a GET request
In order to programmatically access
As a Web Service User
I need to have an ability to make a GET request and check response
Scenario: Make a GET request to Fake Online REST API
When I make GET request to "http://jsonplaceholder.typicode.com/posts/1"
Then the status code should be 200
And content type should be "application/json; charset=utf-8"
And the JSON response should be:
"""
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
"""
Here you need to add 1 step definition where the client makes a GET request
// demo/definitions/get.js
module.exports = function () {
this.When(/^I make GET request to "([^"]*)"$/, function(url, callback) {
this.api.get(url).then(callback);
});
}
and 3 step definitions where tester checks a response returned by client
// demo/definitions/get.js
module.exports = function () {
// ...
this.Then(/^the status code should be (\d+)$/, function(statusCode, callback) {
this.api.assertStatus(statusCode).then(callback);
});
this.Then(/^content type should be "([^"]*)"$/, function(contentType, callback) {
this.api.assertContentType(contentType).then(callback);
});
this.Then(/^the JSON response should be:$/, function(string, callback) {
this.api.assertJSON(JSON.parse(string)).then(callback);
});
}
This is how it works. Once again short about key steps: prepare a request, send it, check a returned response.
-
Actions
-
Assertions
-
Request Property
Sends a GET request to a given path
.
this.api.get(path).then(callback);
###head
Sends a HEAD request to a given path
.
this.api.head(path).then(callback);
###post
Sends a POST request to a given path
.
this.api.post(path).then(callback);
Note: use setBody
method to set a body of request
###patch
Sends a PATCH request to a given path
.
this.api.patch(path).then(callback);
Note: use setBody
method to set a body of request
###put
Sends a PUT request to a given path
.
this.api.put(path).then(callback);
Note: use setBody
method to set a body of request
###delete
Sends a DELETE request to a given path
.
this.api.delete(path).then(callback);
###http
Sends an HTTP request of any request method
to given path
this.api.http(path, method).then(callback);
Note: use proper Request Property
methods to configure a request before sending
All assertions are made only after any request.
###assertContainsChecks if the returned response contains a given value
this.api.contains(value).then(callback);
###assertContentType
Checks if the returned response has a given content type
this.api.assertContentType(contentType).then(callback);
###assertHeaderEquals
Checks if a given header
of the returned response has the expected value
.
this.api.assertHeaderEquals(header, value).then(callback);
###assertHeaderExists
Checks if a given header
exists in the returned response.
this.api.assertHeaderExists(header).then(callback);
###assertHeaderNotExists
Checks if a given header
doesn't exist in the returned response.
this.api.assertHeaderNotExists(header).then(callback);
###assertJSON
Checks if the returned response equals a given object
this.api.assertJSON(json).then(callback);
Note: Use this method only if a response content is in JSON format. Api tester automatically parses the body of response and compares the parsed JSON with given object.
###assertJSONContains
Checks if the JSON content contains given value
by key
.
this.api.assertJSONContains(key, value).then(callback);
Note: key
is a path to a specific element of JSON. Api tester use jspath to match elements. More about jspath look here
###assertJSONElementPresented
Checks if an element by given key
is presented in the JSON content
this.api.assertJSONElementPresented(key).then(callback);
Note: key
is a path to a specific element of JSON. Api tester use jspath to match elements. More about jspath look here
###assertJSONElementNotPresented
Checks if an element by given key
is not presented in the JSON content
this.api.assertJSONElementNotPresented(key).then(callback);
Note: key
is a path to a specific element of JSON. Api tester use jspath to match elements. More about jspath look here
###assertJSONLength
Checks if an element by given key
has a given length
.
this.api.assertJSONLength(key, length).then(callback);
Note: key
is a path to a specific element of JSON. Api tester use jspath to match elements. More about jspath look here
###assertKeysEqual
Checks if an element by given path
has all enumerated keys
.
this.api.assertJSONLength(path, keys).then(callback);
Note: path
is to a specific element of JSON. Api tester use jspath to match elements. More about jspath look here
###assertKeysEqual
Checks if an element by given path
has given values
.
this.api.assertJSONLength(path, values).then(callback);
Note: path
is to a specific element of JSON. Api tester use jspath to match elements. More about jspath look here
###assertStatus
Checks if the response status code equals to given.
this.api.assertStatus(status).then(callback);
###assertStatusNot
Checks if the response status code does not equals to given.
this.api.assertStatusNot(status).then(callback);
###assertText
Checks if the body of returned response equals to given text
.
this.api.assertText(text).then(callback);
###modifyAndAssertJSON
Enables modification of the JSON returned by the server via a custom callback, before the assertion is called. This enables dynamic properties of the returned JSON to be stripped before the comparison is made. This is for applying an assertion in the JSON with a custom callback for modifying the JSON before the comparison takes place, so to account for dynamic response values, like ID fields, for example.
this.api.modifyAndAssertJSON(function(actual_json, call){
var field_name, i;
for (i = 0; i < fields.length; i++) {
field_name = fields[i];
actual_json[field_name] = "";
}
call(exp_json, actual_json);
})
Example usage in a feature:
Then the response should match the following, taking into account that "id,mid" are dynamic fields:
"""
{
"id": "",
"mid": 2310,
"sid": 112,
"lotsofotherfields": "foo",
"etc..."
}
"""
There are methods that help you to configure a request before its sending.
###addHeadersAdds the given headers
to a current request.
this.api.addHeaders(headers).then(callback);
Note: the method doesn't replace previous headers, but merges all with the same names
###addParameters
Adds the given parameters
to the current request. All parameters are converted to query string.
this.api.addParameters(parameters).then(callback);
Note: Don't use it for POST data instead of setBody
method. The given parameters are placed in a query string, not body
###addOptions
Adds the given options
to the current request.
Options alter the default behaviour of the request.
Example options include:
auth
followRedirect
strictSSL
timeout
proxy
this.api.addOptions(options).then(callback);
###addGlobalHeaders
The given headers will be automatically added to each next request during tests execution.
this.api.addGlobalHeaders(headers).then(callback);
###addGlobalParameters
The given parameters will be automatically added to each next request during tests execution.
this.api.addGlobalParameters(parameters).then(callback);
###setBody
Sets a given body
to the current request. It's irreplaceable thing for POST, PUT requests.
this.api.setBody(body).then(callback);
###setGlobals
A tiny tricky method that allows you to set globals in one action. globals
is an object that has 2 properties: headers
and parameters
.
this.api.addGlobalParameters(globals).then(callback);
Attention: Don't use it if you don't understand what you do.
plus.garden.api is distributed under the terms of the MIT license - see the LICENSE
file for details