Giter Site home page Giter Site logo

httpsteps's Introduction

Cucumber HTTP steps for Go

Build Status Coverage Status GoDevDoc Time Tracker Code lines Comments

This module implements HTTP-related step definitions for github.com/cucumber/godog.

Steps

Local Client

Local and remote services can be tested with client request configuration and response expectations.

Please note, due to centralized nature of these mocks they can not be used concurrently by different scenarios. If multiple scenarios configure a shared service, they will be locked in a sync sequence. It is safe to use concurrent scenarios.

Request Setup

When I request HTTP endpoint with method "GET" and URI "/get-something?foo=bar"

In request configuration steps you can specify name of the service to apply configuration. If service name is omitted, default service (with URL passed to NewLocalClient) is used:

  • request HTTP endpoint - default service,
  • request "some-service" HTTP endpoint - service named some-service.

Named services have to be explicitly added with their base URLs before running tests.

When I request "some-service" HTTP endpoint with method "GET" and URI "/get-something?foo=bar"

An additional header can be supplied. For multiple headers, call step multiple times.

And I request HTTP endpoint with header "X-Foo: bar"

An additional cookie can be supplied. For multiple cookies, call step multiple times.

And I request HTTP endpoint with cookie "name: value"

Optionally request body can be configured. If body is a valid JSON5 payload, it will be converted to JSON before use. Otherwise, body is used as is.

And I request HTTP endpoint with body
"""
[
  // JSON5 comments are allowed.
  {"some":"json"}
]
"""

Request body can be provided from file.

And I request HTTP endpoint with body from file
"""
path/to/file.json5
"""

If endpoint is capable of handling duplicated requests, you can check it for idempotency. This would send multiple requests simultaneously and check

  • if all responses are similar or (all successful like GET)
  • if responses can be grouped into exactly ONE response of a kind and OTHER responses of another kind (one successful, other failed like with POST).

Number of requests can be configured with Local.ConcurrencyLevel, default value is 10.

And I concurrently request idempotent HTTP endpoint

Response Expectations

Response expectation has to be configured with at least one step about status, response body or other responses body ( idempotency mode).

If response body is a valid JSON5 payload, it is converted to JSON before use.

JSON bodies are compared with assertjson which allows ignoring differences when expected value is set to "<ignore-diff>".

And I should have response with body
"""
[
  {"some":"json","time":"<ignore-diff>"}
]
"""
And I should have response with body from file
"""
path/to/file.json
"""

Status can be defined with either phrase or numeric code.

Then I should have response with status "OK"
Then I should have response with status "204"

And I should have other responses with status "Not Found"

In an idempotent mode you can check other responses.

And I should have other responses with body
"""
{"status":"failed"}
"""
And I should have other responses with body from file
"""
path/to/file.json
"""

Optionally response headers can be asserted.

Then I should have response with header "Content-Type: application/json"

And I should have other responses with header "Content-Type: text/plain"
And I should have other responses with header "X-Header: abc"

You can set expectations for named service by adding service name before response or other responses:

  • have response - default,
  • have other responses - default,
  • have "some-service" response - service named some-service,
  • have "some-service" other responses - service named some-service.

External Server

External Server mock creates an HTTP server for each of registered services and allows control of expected requests and responses with gherkin steps.

It is useful describe behavior of HTTP endpoints that are called by the app during test (e.g. 3rd party APIs).

Please note, due to centralized nature of these mocks they can not be used concurrently by different scenarios. If multiple scenarios configure a shared service, they will be locked in a sync sequence. It is safe to use concurrent scenarios.

In simple case you can define expected URL and response.

Given "some-service" receives "GET" request "/get-something?foo=bar"

And "some-service" responds with status "OK" and body
"""
{"key":"value"}
"""

Or request with body.

And "another-service" receives "POST" request "/post-something" with body
"""
// Could be a JSON5 too.
{"foo":"bar"}
"""

Request with body from a file.

And "another-service" receives "POST" request "/post-something" with body from file
"""
_testdata/sample.json
"""

Request can expect to have a header.

And "some-service" request includes header "X-Foo: bar"

By default, each configured request is expected to be received 1 time. This can be changed to a different number.

And "some-service" request is received 1234 times

Or to be unlimited.

And "some-service" request is received several times

By default, requests are expected in same sequential order as they are defined. If there is no stable order you can have an async expectation. Async requests are expected in any order.

And "some-service" request is async

Response may have a header.

And "some-service" response includes header "X-Bar: foo"

Response must have a status.

And "some-service" responds with status "OK"

Response may also have a body.

And "some-service" responds with status "OK" and body
"""
{"key":"value"}
"""
And "another-service" responds with status "200" and body from file
"""
_testdata/sample.json5
"""

Dynamic Variables

When data is not known in advance, but can be inferred from previous steps, you can use dynamic variables.

Here is an example where value from response of one step is used in request of another step.

  Scenario: Creating user and making an order
    When I request HTTP endpoint with method "POST" and URI "/user"

    And I request HTTP endpoint with body
    """json
    {"name": "John Doe"}
    """

    # Undefined variable infers its value from the actual data on first encounter.
    Then I should have response with body
    """json5
    {
      // Capturing dynamic user id as $user_id variable.
     "id":"$user_id",
     "name": "John Doe",
     // Ignoring other dynamic values.
     "created_at":"<ignore-diff>","updated_at": "<ignore-diff>"
    }
    """

    # Creating an order for that user with $user_id.
    When I request HTTP endpoint with method "POST" and URI "/order"

    And I request HTTP endpoint with body
    """json5
    {
      // Replacing with the value of a variable captured previously.
      "user_id": "$user_id",
      "item_name": "Watermelon"
    }
    """
    # Variable interpolation works also with body from file.

    Then I should have response with body
    """json5
    {
     "id":"<ignore-diff>",
     "created_at":"<ignore-diff>","updated_at": "<ignore-diff>",
     "user_id":"$user_id"
    }
    """

Example Feature

Feature: Example

  Scenario: Successful GET Request
    Given "template-service" receives "GET" request "/template/hello"

    And "template-service" responds with status "OK" and body
    """
    Hello, %s!
    """

    When I request HTTP endpoint with method "GET" and URI "/?name=Jane"

    Then I should have response with status "OK"

    And I should have response with body
    """
    Hello, Jane!
    """

httpsteps's People

Contributors

vearutop avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.