HTTP and REST API

Testerum comes with a new and easy way to test your REST API.
With Testerum, you’ll be able to send HTTP Requests and verify HTTP Responses from an intuitive UI, without having to write any line of code.
Http Request - Response

HTTP Request

  • Create a new Feature
  • Let's start by creating a new test and add the HTTP Request Step (img 1):
    1. First of all hover your mouse cursor over a feature file and press the Create Test button
    2. Set a test name
    3. Click the Add Step button
    4. Click the Select Step button
    img 1
    Empty test

    After you click on the "+" button in the Steps section, a new window will pop up. Go to Basic Steps -> http -> request and select the step When I execute the HTTP request <<httpRequest>> (img 2).

    img 2
    Select HTTP Request Step

    Now, click the "Edit" button to define the HTTP Request parameter (img 3).

    img 3
    Edit HTTP Request param

    In the opened popup, you can define all your HTTP Request details (img 4):

    1. Set a Name that describes what is this request about
    2. Set the Request Method: GET, POST, PUT, DELETE, etc.
    3. Set the Request URL.
      In this example the Request URL is composed of the value of the variable URL and the suffix /api/auth/login
    4. In the Headers tab you can define the Request Headers.
    5. All the Request Methods beside GET allow you to define the Request Body.
    6. In case you are testing a REST API set the Request Body as raw and the content type as JSON
      . Setting the content type as JSON you will have syntax highlight and validation plus the Format JSON option.
    7. Using the Params button will reveal the Query Param panel that allows you to define query parameters that will be automatically be encoded for you.
    8. When you have your request defined you can use the Execute Request button to check if is what you want and to see the server response.
    9. When your HTTP Request is defined press the OK button.
    img 4
    Edit HTTP Request param

    Data extraction

    In this section you’ll learn how to extract data from an HTTP request and store this value into a variable. Next we will use this value in a different request. Let's execute the request defined in the previous chapter to see the response (img 5):

    1. After the test is saved the Run Test button will be displayed. Click this button to execute the test.
    2. After clicking the Run Test button the Test Execution Panel will be displayed.
      • on the left side there is the Execution Overview Panel
      • on the right side there is the Console where all the logs generated during current execution are shown.
    3. In the console you can see the executed HTTP Request and HTTP Response details.
    4. In this example we see that the HTTP Response Body is:
      {
          "authToken": "YWRtaW46YWRtaW4="
      }
      
      Let's extract the value of the "authToken" and store it in a variable.
    img 5
    Execute the HTTP Request test


    1. In order to extract the "authToken" value from the HTTP Response we need to use the following step (img 6):
      Extract variable step
    2. We will set the step parameter name to AUTH_TOKEN
    3. To extract the value from the response we are going to use the following expression: {{httpResponse.jsonBody.authToken}} After each HTTP Request two variables are created: httpResponse and httpRequest.

      Let me explain you the above expression, {{httpResponse.jsonBody.authToken}}:
      • httpResponse is accessible after an HTTP Request is made and gives you access to all the HTTP Response details.
      • jsonBody returns the HTTP Response Body as a JSON object. This will allow you to access the JSON as an JavaScript Object.
      • authToken returns the value of the authToken property from the HTTP Response.
    img 6
    Extract variable from HTTP Response

    Let's add a new step that executes another HTTP Request and which uses the AUTH_TOKEN variable (img 7):

    1. Added a new HTTP Request step "add customer"
    2. This request requires the Header Authorization that uses the variable AUTH_TOKEN.
      To access the value of this variable we use the expression: {{AUTH_TOKEN}}
    3. At runtime the expression {{AUTH_TOKEN}} will be evaluated and replaced with the variable's value.
    4. We are going to use this request later on to show you how we can do an HTTP Response Validation.
    img 7
    Add customer HTTP Response

    HTTP Expressions

    In the previous section you learned how to extract parts of a JSON response by using an expression like {{httpResponse.jsonBody.authToken}}.
    This section describes other expressions which are available.

    After making an HTTP request, two variables are created: httpResponse and httpRequest. In the following section, we describe the models for these variables.

    Response

    protocol         : String,  // HTTP/1.1
    statusCode       : int,     // 200
    headers          : List<HttpResponseHeader>,
    body             : byte[],  // body, exactly as received
    bodyAsUtf8String : String,
    jsonBody         : Map<String, String | int | boolean | null | Map}>  // httpResponse.jsonBody.person.name
    durationInMillis : Long
    getHeaderValue(key: String) : String   // returns the first header value for the provided key or null

    HttpResponseHeader

    key    : String,      // Content-Type
    values : List<String> // we use a list to capture all values (HTTP allows a header to be specified multiple times)

    Request

    method          : HttpRequestMethod,
    url             : String
    headers         : Map<String, String>,
    body            : HttpRequestBody | null,
    followRedirects : boolean

    HttpRequestMethod

    enum {
        GET,
        POST,
        PUT,
        DELETE,
        HEAD,
        OPTIONS,
        TRACE,
        PATCH
    }

    HttpRequestBody

    bodyType : HttpRequestBodyType
    content  : String

    HttpRequestBodyType

    enum {
        RAW,
        FORM_DATA,
        X-WWW-FORM-URLENCODED,
        BINARY
    }

    HTTP Verify

    Let's see how we can verify the previous executed HTTP Request (img 7).
    For this we are going to add the following step to our test:
    HTTP Verify step

    Let's edit the httpResponseVerify parameter and set the HTTP Response Verify details (img 8):
    1. Set a name for this Http Response Verify
    2. Set the expected Status Code
    3. Set the expected headers. There are multiple ways to compare the headers value:
      • EXACT MATCH - the actual value must be exactly equal to the expected value specified here
      • CONTAINS - the actual value must contain the expected value
      • MATCH REGEX - the actual value must match the expected regular expression. See the documentation on the exact syntax of the regular expression.
    4. Testerum provides different Body Matching options:
      • JSON Verify: makes JSON Comparison very easy, more about this in the JSON Verify section
      • Exact Match: the actual response body must be exactly the same as the expected body
      • Contains: the actual response body must contain the expected body
      • Match Regex: the actual response body must match the expected regular expression. See the documentation on the exact syntax of the regular expression.
      • Is Empty: the actual response body must not contain any characters, not even whitespace
    5. Comparison Mode allows you to set on each JSON Node how to be compared with the actual response.
      Comparison Mode has three possible options: exact, unorderExact and contains. More about this option in the JSON Verify chapter.
    6. To verify the JSON Body Response, just copy - paste the response or type it from scratch and use the following rules:
      • You can use Assertion functions to check the value: @isNotEmpty(), @isNotNull(), @isNullOrEmpty(), @isBlank(), @isNullOrBlank(), @isNotBlank(), @matchesRegex("[0-9]") and many more here.
        For example: normally the ID fields of an object are generated and for checking their value we can use the function @isNotEmpty().
      • If there are fields or objects that you are not interested in checking if they exist or which value they have, just remove them from the expected JSON.
        In this example in the expected JSON we have removed the fields address.postCode and address.houseNumber.
    img 8
    HTTP Response Verify

    JSON Verify

    One of the innovations in Testerum is how easy is to compare two JSONs. This functionality can be accessed using one of the following steps:

    Expected JSON Panel

    Simple verification

    The simplest verification is to put in the expected body as-is:
    Actual JSON
    {
        "id": 3476,
        "firstName": "John",
        "lastName": "Doe"
    }
    Expected JSON
    {
        "id": 3476,
        "firstName": "John",
        "lastName": "Doe"
    }

    Assertion functions

    Instead of expecting a particular value, you can use comparison functions:
    Actual JSON
    {
        "id": 3476,
        "firstName": "John",
        "lastName": "Doe"
    }
    Expected JSON
    {
        "id": "@isNotEmpty()",
        "firstName": "John",
        "lastName": "Doe"
    }
    In this case the actual JSON will match because 3476 satisfies the @isNotEmpty() function.
    img 9
    HTTP Json Schema Validation

    In the picture above(img 9) we have on the left side a simple HTTP Response verification which works fine, and on the right side we validate the JSON using some of the Testerum assertion functions "@isNotEmpty()", "@isArray()", "@isBoolean()". In this case the actual JSON will match because:

    If you want to compare against a text that begins with @, you will have to escape it: "\\@alex says thanks". Available Testerum assertion functions to validate the JSON:






    Compare Modes

    Using the Compare Mode you can test any JSON in the smallest details.
    In the Expected JSON you can specify on each node how to be compare with the equivalent node in the Actual JSON.
    Let's see a complex scenario and understand how it works (img 10):
    img 10
    HTTP Response Verify
    this comparison will pass
    1. to set a compare mode on a node you need to:
      • set the cursor inside the node you want to set or change the compare mode
      • choose from the drop-down element one of the 3 options: exact, unorderExact, contains
      • press the Insert button
    2. Setting "=compareMode": "exact" to an object node means that all the properties in the Actual JSON needs to be present in the Expected JSON.
    3. Setting "=compareMode": "contains" to an object node means that not all the properties in the Actual JSON needs to be present in the Expected JSON.
      In our example we are interested to compare only the "address/city" and "address/street", so the fields "address/postCode" and "address/houseNumber" will be ignored in the comparison.
    4. Setting "=compareMode: unorderedExact" on the array will check that all the nodes from the Actual JSON are present in the Expected JSON but the order is not important.
      As you see =compareMode property format is different on the array than on a object node.
      The option unorderedExact makes sens only on an array node. In an object node, the order of the properties is always ignored.
    5. Because the compare mode is "contains" will have the effect that the node "favFoods" will be ignored in comparion.
    NOTES:

    Compare modes - Contains

    The actual comparison is done according to a compare mode. The default compare mode is contains:
    Actual JSON
    {
        "id": 3476,
        "firstName": "John",
        "lastName": "Doe"
    }
    Expected JSON
    {
        "firstName": "John",
        "lastName": "Doe"
    }
    or
    Actual JSON
    {
        "id": 3476,
        "firstName": "John",
        "lastName": "Doe"
    }
    Expected JSON
    {"=compareMode": "contains"
        "firstName": "John"
    }
    Because the compare mode is contains, the actual JSONs above will match the expected JSONs, even though it has extra fields.

    Compare modes - Exact

    If you want the actual to have exactly the same fields as the expected, you need to use the exact compare mode:
    Actual JSON
    {
        "id": 3476,
        "firstName": "John",
        "lastName": "Doe"
    }
    Expected JSON
    {"=compareMode": "exact"
        "firstName": "John",
        "lastName": "Doe"
    }
    This will not match, because the compare mode is exact, but the Actual JSON has an extra field (id).

    Compare modes - Unordered exact

    The compare mode unorderedExact is like exact, but ignores the order of items in an array:
    Actual JSON
    [
        "Bari",
        "Messina",
        "Siena"
    ]
    Expected JSON
    ["=compareMode: unorderedExact",
        "Messina",
        "Siena",
        "Bari"
    ]
    This will match.
    The compare mode unorderedExact makes sens to be used only on arrays.

    Compare modes per JSON node

    The comparison can be done for the entire verification, as well as for each node in the JSON:
    Actual JSON
    [
        {
            "id": 14,
            "firstName": "Alex",
            "lastName": "Thompson"
        },
        {
            "id": 27,
            "firstName": "John",
            "lastName": "Doe"
        }
    ]
    Expected JSON
    ["=compareMode: contains",
        {"=compareMode": "exact",
            "id": "@isNotEmpty()",
            "firstName": "John",
            "lastName" : "Doe",
        }
    ]

    This will match.

    How different compare modes interact