Skip to content

Latest commit

 

History

History
494 lines (406 loc) · 17.9 KB

File metadata and controls

494 lines (406 loc) · 17.9 KB

OpenAPI Postman test suite generation - overwrites

In the examples/testsuite-contract-tests example, we explained the default generated Postman contract tests.

This example focuses on the manipulation of the Postman collection to make it possible to automate, by manipulating:

  • Request bodies
  • Request headers
  • Request query params
  • Request path variables

use-cases:

  • Generate Postman flows that require unique values
  • Reference a created entity to be used in Read/Update/Delete flows by setting the ID reference as query parameter
  • Overwrite an example value with an actual value that exists in the API

CLI usage

portman --cliOptionsFile ./examples/testsuite-overwrites/portman-cli-options.json

Configured by using the portman-cli config.

This is an example where we take the OpenAPI defined in crm.yml, with only 1 entity (leads) to keep the example simple and overwrite specific values in the generated Postman collection.

Portman settings

The portman settings (in JSON format) consists out of multiple parts, in this example we focus on the overwrites section and settings.

file: examples/testsuite-overwrites/portman-config.crm.json

Portman - "overwrites" properties

Version 1.0

To facilitate automation, you might want to modify property values with "randomized" or specific values. The overwrites are mapped based on the OpenAPI operationId or OpenAPI Operation reference.

Target options:

  • openApiOperationId (String) : Reference to the OpenAPI operationId for which the Postman request body will be extended. (example: leadsAll)
  • openApiOperation (String) : Reference to combination of the OpenAPI method & path, for which the Postman request body will be extended (example: GET::/crm/leads)

These target options are both supported for defining a target. In case both are set for the same target, only the openApiOperationId will be used for overwrites. See below for more options on targeting.

Overwrite options:

  • overwriteRequestQueryParams (Array) :

    Array of key/value pairs to overwrite in the Postman Request Query params.

    • key (String) : The key that will be targeted in the request Query Param to overwrite/extend.
    • value (Any) : The value that will be used to overwrite/extend the value in the request Query Param OR use the Postman Dynamic variables to use dynamic values like {{$guid}} or {{$randomInt}}. The value can be a text/number/boolean/array/object or Postman variable (to pass the Postman variable as type boolean or number, use {{{variableName}}} surrounded by 3x {{{ and 3x }}}).
    • overwrite (Boolean true/false | Default: true) : Overwrites the request query param value OR attach the value to the original request query param value.
    • disable (Boolean true/false | Default: false) : Disables the request query param in Postman.
    • remove (Boolean true/false | Default: false) : Removes the targeted request query param from Postman.
    • insert (Boolean true/false | Default: true) : Insert additional the request query param in Postman that are not present in OpenAPI.
  • overwriteRequestPathVariables (Array) :

    Array of key/value pairs to overwrite in the Postman Request Path Variables.

    • key (String) : The key that will be targeted in the request Path variables to overwrite/extend.
    • value (String) : The value that will be used to overwrite/extend the value in the request path variable OR use the Postman Dynamic variables to use dynamic values like {{$guid}} or {{$randomInt}}.
    • overwrite (Boolean true/false | Default: true) : Overwrites the request path variable value OR attach the value to the original request Path variable value.
    • remove (Boolean true/false | Default: false) : Removes the targeted request path variable from Postman.
    • insert (Boolean true/false | Default: true) : Insert additional the request path variable in Postman that are not present in OpenAPI.
    • description (String) : Optional, Overwrites the request path variable description in Postman.
  • overwriteRequestHeaders (Array) :

    Array of key/value pairs to overwrite in the Postman Request Headers.

    • key (String) : The key that will be targeted in the request headers to overwrite/extend.
    • value (String) : The value that will be used to overwrite/extend the value in the request headers OR use the Postman Dynamic variables to use dynamic values like {{$guid}} or {{$randomInt}}.
    • overwrite (Boolean true/false | Default: true) : Overwrites the request header value OR attach the value to the original request header value.
    • disable (Boolean true/false | Default: false) : Disables the request headers param in Postman.
    • remove (Boolean true/false | Default: false) : Removes the targeted request headers from Postman.
    • insert (Boolean true/false | Default: true) : Insert additional the request headers in Postman that are not present in OpenAPI.
  • overwriteRequestBody (Array) :

    Array of key/value pairs to overwrite in the Postman Request Body.

    • key (String) : The key that will be targeted in the request body to overwrite/extend.
    • value (String) : The value that will be used to overwrite/extend the key in the request body OR use the Postman Dynamic variables to use dynamic values like {{$guid}} or {{$randomInt}}.
    • overwrite (Boolean true/false | Default: true) : Overwrites the request body value OR attach the value to the original request body value.
    • remove (Boolean true/false | Default: false) : Removes the request body property, including the value.

Example explained

In this example, we are zooming in on only the overwrites usage. For the basics on the testsuite configuration and usage in Portman, have a look at examples/testsuite-contract-tests

file: examples/testsuite-overwrites/portman-config.crm.json >>

{
  "version": 1.0,
  "overwrites": [
    {
      "openApiOperationId": "leadsAdd",
      "overwriteRequestBody": [
        {
          "key": "name",
          "value": "--{{$randomInt}}",
          "overwrite": false
        },
        {
          "key": "company_name",
          "value": "{{$randomCompanyName}} {{$randomColor}}",
          "overwrite": true
        },
        {
          "key": "monetary_amount",
          "value": "{{$randomInt}}",
          "overwrite": true
        },
        {
          "key": "websites[0]",
          "remove": true
        },
        {
          "key": "social_links[1].url",
          "remove": true
        },
        {
          "key": "@count",
          "value": false,
          "overwrite": true
        }
      ]
    },
    {
      "openApiOperation": "DELETE::/crm/leads/{id}",
      "overwriteRequestQueryParams": [
        {
          "key": "raw",
          "value": "false",
          "overwrite": true
        }
      ],
      "overwriteRequestPathVariables": [
        {
          "key": "id",
          "value": "123456789",
          "overwrite": true
        },
        {
          "key": "id",
          "remove": true
        }
      ]
    },
    {
      "openApiOperationId": "leadsOne",
      "overwriteRequestPathVariables": [
        {
          "key": "id",
          "value": "<operationId>_<pathPart1>"
        }
      ]
    },
    {
      "openApiOperationId": "leadsUpdate",
      "overwriteRequestHeaders": [
        {
          "key": "x-apideck-consumer-id",
          "value": "portman-id-{{$randomInt}}",
          "overwrite": true
        },
        {
          "key": "x-apideck-consumer-id-additional",
          "value": "portman-id-{{$randomInt}}-additional"
        }
      ],
      "overwriteRequestBody": [
        {
          "key": "description",
          "value": "{{newDescription}}",
          "overwrite": true
        },
        {
          "key": "monetary_amount",
          "value": "{{{newMonetaryAmount}}}",
          "overwrite": true
        }
      ],
      "overwriteRequestPathVariables": [
        {
          "key": "id",
          "value": "123456789",
          "overwrite": true,
          "description": "Lead ID"
        }
      ]
    },
    {
      "openApiOperationId": "leadsAll",
      "overwriteRequestQueryParams": [
        {
          "key": "limit",
          "disable": true
        },
        {
          "key": "cursor",
          "remove": true
        },
        {
          "key": "count",
          "value": "yes",
          "disable": true,
          "description": "Get total result count"
        }
      ]
    },
    {
      "openApiOperationId": "leadsAll",
      "overwriteRequestSecurity": {
        "bearer": {
          "token": "{{managementToken}}"
        }
      }
    }
  ],
  "globals": {
    "stripResponseExamples": true,
    "collectionVariables": {
      "newDescription": "a spaceman",
      "newMonetaryAmount": 150000
    }
  }
}

Let's break this down into it's different parts to understand what is happening.

overwriteRequestBody

{
  "openApiOperationId": "leadsAdd",
  "overwriteRequestBody": [
    {
      "key": "name",
      "value": "{{$randomName}}",
      "overwrite": false
    },
    {
      "key": "company_name",
      "value": "{{$randomCompanyName}} {{$randomColor}}",
      "overwrite": true
    },
    {
      "key": "monetary_amount",
      "value": "{{{$randomInt}}}",
      "overwrite": true
    },
    {
      "key": "websites[0]",
      "remove": true
    },
    {
      "key": "social_links[1].url",
      "remove": true
    }
  ]
}

This will target the OpenAPI "openApiOperationId": "leadsAdd" and will overwrite the request body.

  1. the name property will be extended (because overwrite:false) with {{$randomName}}
  2. the company_nameproperty will be overwritten (because overwrite:true) with {{randomCompanyName}} {{randomColor}}
  3. the monetary_amount property will be overwritten (because overwrite:true) with {{$randomInt}}.
  4. the "websites[0] item will be removed (because remove:true), which will results in the 1st item in the websites array to be removed. The index of the array will be reset.
  5. the social_links[1].url property will be removed (because remove:true) with the nested url property from the 2nd item of the social_links array removed.

The first three settings all use Postman Dynamic variables. Indicated by the "$" at the beginning of the variable names, these are predefined variables that are built into Postamn. Portman is aware of the types of Postman dynamic variables and will put quotes around the variable in the generated request body when the variable is typically treated as a string. So in our example, {{$randomName}} and {{randomCompanyName}}, will be enclosed in quotes in the generated request body, but {{$randomInt}} will not be.

This behavior differs slightly when setting request body properties to Postman Collection Variables

After the conversion, in the "leadsAdd" request (POST::/crm/leads) in the Postman app, you can find the following result in the request body.

file: examples/testsuite-overwrites/crm.postman.json >>

Postman request "Leads" >> "Create lead" Request body:

{
  "name": "Elon Musk--{{$randomInt}}",
  "company_name": "{{$randomCompanyName}} {{$randomColor}}",
  "owner_id": "54321",
  "company_id": "2",
  "contact_id": "2",
  "first_name": "Elon",
  "last_name": "Musk",
  "description": "A thinker",
  "monetary_amount": {{$randomInt}},
  "websites": [
    {
      "url": "http://example.com",
      "id": "12345",
      "type": "primary"
    }
  ],
  "social_links": [
    {
      "url": "https://www.twitter.com/apideck-io",
      "id": "12345",
      "type": "twitter"
    },
    {
      "id": "12345",
      "type": "twitter"
    }
  ]
}

Each time the request is executed in Postman, the {{$random}} variables will be generated with random values like defined on the Postman Dynamic variables page.

overwriteRequestQueryParams

{
  "openApiOperation": "DELETE::/crm/leads/{id}",
  "overwriteRequestQueryParams": [
    {
      "key": "raw",
      "value": "false",
      "overwrite": true
    }
  ]
}

This will target the OpenAPI "openApiOperation": "DELETE::/crm/leads/{id}" and will overwrite the request query params.

  1. The raw property will be overwritten (because overwrite:true) with "false"

After the conversion, in the "leadsDelete" request (DELETE::/crm/leads/{id}) in the Postman app, you can find the following result in the request query params.

file: examples/testsuite-overwrites/crm.postman.json >>

Postman request "Leads" >> "Delete lead" Request query params:

The example below will showcase the "disable" setting.

{
  "openApiOperationId": "leadsAll",
  "overwriteRequestQueryParams": [
    {
      "key": "limit",
      "disable": true
    },{
      "key": "cursor",
      "remove": true
    },{
      "key": "count",
      "value": "yes",
      "disable": true,
      "description": "Get total result count"
    }
  ]
}

This will target the OpenAPI "openApiOperationId": "leadsAll" .

  1. The request query params will set the limit property as disabled (because disable:true) in Postman.
  2. Remove the request cursor query param (because remove:true) from Postman.
  3. Insert the new request count query param into the Postman collection, with a value & description.

file: examples/testsuite-overwrites/crm.postman.json >>

Postman request "Leads" >> "Get leads" Request query params:

overwriteRequestPathVariables

{
  "openApiOperation": "DELETE::/crm/leads/{id}",
  "overwriteRequestPathVariables": [
    {
      "key": "id",
      "value": "123456789",
      "overwrite": true
    }
  ]
}

This will target the OpenAPI "openApiOperation": "DELETE::/crm/leads/{id}" and will overwrite the request query params.

  1. the idproperty will be overwritten (because overwrite:true) with 123456789

After the conversion, in the "leadsDelete" request (DELETE::/crm/leads/{id}) in the Postman app, you can find the following result in the request Path variables.

file: examples/testsuite-overwrites/crm.postman.json >>

Postman request "Leads" >> "Delete lead" Request query params:

overwriteRequestHeaders

{
  "openApiOperationId": "leadsUpdate",
  "overwriteRequestHeaders": [
    {
      "key": "x-apideck-consumer-id",
      "value": "portman-id-{{$randomInt}}",
      "overwrite": true
    },
    {
      "key": "x-apideck-consumer-id-additional",
      "value": "portman-id-{{$randomInt}}-additional"
    }
  ]
}

This will target the OpenAPI "openApiOperationId": "leadsUpdate" and will overwrite the request query headers.

  1. the x-apideck-consumer-id header property will be overwritten (because overwrite:true) with portman-id-{{$randomInt}}
  2. the x-apideck-consumer-id-additional header does not exist, so this new header will be inserted with portman-id-{{$randomInt}}-additional

After the conversion, in the "leadsUpdate" request (PATCH::/crm/leads/{id}) in the Postman app, you can find the following result in the headers tab.

file: examples/testsuite-overwrites/crm.postman.json >>

Postman request "Leads" >> "Update lead" Request headers:

overwriteRequestBody with Postman Collection Variables

"overwrites": [
  {
    "openApiOperationId": "leadsUpdate",
    "overwriteRequesBody": [
      {
        "key": "description",
        "value": "{{newDescription}}",
        "overwrite": true
      }
      {
        "key": "monetary_amount",
        "value": "{{{newMonetaryAmount}}}",
        "overwrite": true
      }
    ]
  }
],
"globals": {
  "collectionVariables": [
    {
      "name": "newDescription",
      "value": "a spaceman"
    },
    {
      "name": "newMonetaryAmount",
      "value": 150000
    }
  ]
}

This will also target the OpenAPI "openApiOperationId": "leadsUpdate" and will overwrite the request body using Postman Collection Variables. In this example we use collection variables that are set using the collectionVariables directive in the globals section of our configuration

  1. the description property of the request body will be overwritten (because overwrite:true) with "{{newDescription}}". The variable name will be in quotes, because by default Portman treats Postman collection variables as strings.
  2. the monetary_amount property of the request will be overwritten (because overwrite:true) with {{newMonetaryAmount}}. The variable name will be NOT be in quotes, because we use three curly braces instead of two to instruct Portman to override the default behavior of treating Postman collection variables as strings.

After the conversion, in the "leadsUpdate" request (PATCH::/crm/leads/{id}) in the Postman app, you can inspect the request body and see that the generated request body looks like this.

file: examples/testsuite-overwrites/crm.postman.json >>

When assigning request body properties to Postman collection or dynamic variables, the following guidelines can be used:

  • Use Postman Dynamic variable as a string: "{{$randomCompanyName}}"
  • Use Postman Dynamic variable as a number: "{{$randomInt}}"
  • Use Postman variables as a string: "{{yourVar}}"
  • Use Postman variables as number: "{{{yourNumberVar}}}"