The REST Library

/* @provengo summon rest */

The REST library helps testing systems that support RESTful API (often referred to as "REST API" or even just "API"). Effectively methods in this library perform HTTP calls and validate the responses, so it is also possible to use this library for testing raw HTTP interactions with web-based user interfaces, or SOAP services.

In order to make the usage easier and less repetitive, the library uses a session object that manages common data and default options, such as the base URL for the REST endpoint. This way, when calling the endpoints of the service under test, users only need to add data that is unique to the call.

Currently, Provengo supports the following HTTP methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, and TRACE.

Example

In the example below, we use the REST library to test a customer list application. We post a new customer, and validate that said customer was successfully added.

// @provengo summon rtv   (1)
// @provengo summon rest

const svc = new RESTSession(SERVER_ENDPOINT, "client", {                    (2)
    headers: {"Content-Type":"application/json"}
});

bthread("Main", function(){
    // Generate customer data
    const fName = select("first_name").from("Joe", "Jane", "John", "Jill"); (3)
    const lName = select("last_name").from("Smith", "Doe", "Johnson");
    const age = select("age").from("15", "30", "45", "75");

    // Create new customer
    svc.post("/customers", {                                              (4)
        body: JSON.stringify({
                "first_name":fName,
                "last_name":lName,
                "age": age
            }),
        callback: function(response){                                     (5)
            const respObj = JSON.parse(response.body);
            if ( ! respObj.success ) {
                pvg.fail("customer creation failed: " + respObj.message);

            } else {
                pvg.rtv.set("customer_id", respObj.response.ID);          (6)
                pvg.log.info(`new customer id: ${respObj.response.ID}`);  (7)
                pvg.success("New customer created");                      (8)
            }
        }
    });

    // Validate new customer exists
    svc.get("/customers", {                                               (9)
        parameters:{"id":"@{customer_id}"},
        expectedResponseCodes: [200]
    });
});
  1. Importing the REST and Runtime Variables libraries.

  2. Defining a REST session with default headers.

  3. Generating customer data

  4. Performing a HTTP POST request to the server. Client data is wrapped in the body as JSON.

  5. Callback function is used parse the server response, validate that the request was successful and to and extract the new customer id.

  6. Storing the new customer id in the variable runtime system.

  7. Writing the new customer id to the log.

  8. Marking the the test step as a success.

  9. Performing a HTTP GET request with the new customer id, and validating that the response is 200 OK.

Read more about the pvg object here.

Classes

RESTSession(baseURL, sessionName, defaultOptions)

Constructs a new REST session. All calls from this session will be sent to endpoints under baseURL. For example, a server at https://api.fruits.org can have endpoints such as http://api.fruits.org/apples and http://api.fruits.org/bananas. In this case, the base URL should be http://api.fruits.org, and /apples and /bananas are the relative URLs or the service endpoints.

baseURL

The URL of the server exposing the endpoints.

sessionName

Optional. Name of the session.

defaultOptions

Optional. Object containing default options for RESTful API calls. Actual API calls will use these parameters unless they are invokes with other parameters.

headers

Object. HTTP headers.

parameters

Object. Parameters added to the URL.

expectedResponseCodes

Integer Array. Expected response status codes.

callback

Function. Used to validate the response and update runtime values as needed. See Options for more details.

Example

Constructing a new REST session for later use.

const recipeSvc = new RESTSession("https://api.recipes.com/", {
    headers: {
        "Content-Type":"application/json",
        "Api-Key":"my-secret-api-key-so"
        },
    parameters: {
        "lang":"en"
    }
});

bthread("API User", function(){
    recipeSvc.get("/cake/chocolate", {...})
});

Methods

The REST/HTTP methods share many parameters. They are explained in further detail in the Options section.

session.post(url, options)

Sends a POST http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, body, expected return codes, etc. See Options.

session.get(url, options)

Sends a GET http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, expected return codes, etc. See Options. Note that GET methods have no body, so if a params contains a body field, that field is ignored.

session.put(url, options)

Sends a PUT http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, expected return codes, etc. See Options.

session.patch(url, options)

Sends a PATCH http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, expected return codes, etc. See Options.

session.head(url, options)

Sends a HEAD http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, expected return codes, etc. See Options. Note that the HTTP HEAD method does not have a body, so if a params contains a body field, that field is ignored.

session.delete(url, options)

Sends a DELETE http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, expected return codes, etc. See Options. Note that the HTTP DELETE method does not have a body, so if a options contains a body field, that field is ignored.

session.options(url, options)

Sends an OPTIONS http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, expected return codes, etc. See Options. Note that the HTTP OPTIONS method does not have a body, so if a options contains a body field, that field is ignored.

session.trace(url, options)

Sends a TRACE http request to the specified endpoint, and inspects the response.

url

String. RESTful API endpoint relative to the session’s baseURL.

options

Object. HTTP call parameters, including headers, expected return codes, etc. See Options. Note that the HTTP TRACE method does not have a body, so if a options contains a body field, that field is ignored.

Options

A set of options that affect how HTTP requests are sent, and how HTTP responses are validated. All fields are optional.

headers

Object containing the headers fields, where the keys hold the headers name, and the values hold headers contents. To duplicate a header, use an array of values instead of a single value.

parameters

Object containing request parameters. These parameters will be appended to the URL, in the parameter part (i.e. after the ?).

body

String. Body of the HTTP request. NOTE: When passed to HTTP methods that do not have a body, namely GET, HEAD, DELETE, OPTIONS, and TRACE, this field is ignored.

expectedResponseCodes

An array of expected HTTP response status codes. If omitted, Provengo will accept any response status code in what the HTTP standard protocol defines as the "successful range": 200 to 299, inclusive.

callback

A function for validating the response, which it gets as a parameter. It can interact with the runtime values subsystem and report validation results via the pvg service object, exposed as a global variable.

response

Object. The HTTP response. Fields: headers, body, code and version.

response.code:      int
response.headers:   Object (keys and values are all Strings)
response.version:   String
response.body:      String

Properties

session.baseURL

The URL prefix for all service endpoints. Often this is the URL of the server running the service.

session.name

Name of the REST session.

Events

The REST library uses standard Provengo events. Request data is contained in the event’s .data field.

data.method

String. HTTP method name. One of "GET", "POST", "PUT", "PATCH", "HEAD", "DELETE", "OPTIONS", or "TRACE".

data.url

String. The full URL of the request.

data.headers

Object. Contains key-value pairs of header name and values.

data.parameters

Object. Contains key-value pairs of parameter name and values.

data.expectedResponseCodes

Number array. Contains expected response status codes.

data.callback

Function. A callback function invoked when the response arrives.

Example

The code below prevents any DELETE API calls from being sent while other parts of the model are busy testing entity management API endpoints. This prevents flakey tests where entities are deleted by one part of the model, while other parts of the model are trying to edit them.

bthread("no delete while testing", function(){
    let deleteEvents = EventSet("deletes", function(e){  (1)
        return (!!e.data) && e.data.method==="DELETE";
    });
    waitFor(Ctrl.markEvent("User Created"));
    sync({                                               (2)
        block: deleteEvents,
        waitFor: Ctrl.markEvent("User testing done")
    });
});
  1. An event set containing all REST API calls to a DELETE method.

  2. By blocking deleteEvents while waiting for the test finish marker, this prevents users from being deleted while other tests are in progress.