Test Format

Gabbi tests are expressed in YAML containing an HTTP request and an expected response. Each YAML file is an ordered sequence of requests. The bare minimum YAML file for a single request is:

tests:
   - name: the name of a test
     url: /

This will make a request to / on whatever the configured Target Host is. The test will pass if the status of the HTTP response is 200.

The tests sequence can contain as many requests as required. Other top level keys are:

  • fixtures: A sequence of named Fixtures.
  • defaults: A dictionary of local default values for the requests and responses in the tests in this file. These override the global defaults (explained below).

Each test can use the following structure. Only name and url are required. For examples see the gabbi tests, Test Example and the gabbi-demo tutorial.

Many of these items allow substitutions (explained below).

  • name: The name of the test. Must be unique in this file. When tests are dynamically generated the TestCase name will include this name, lowercased with spaces transformed to _. In at least some test runners this will allow you to select and filter on test name. Required

  • desc: An arbitrary string describing this test. This is perhaps redundant as YAML allows comments. However it’s here in case other tooling might use it.

  • url: The URL to request. This can either be a full path or a fully qualified URL (with host and scheme). If not qualified the test builder will be responsible for determining host and scheme. Required

  • query_parameters: An optional dictionary of query parameters that will be added to the url as query string. If the url already contains a set of query parameters, those wil be extended. See Test Example for a demonstration of how the data is structured.

  • method: The request method to use. Defaults to GET.

  • status: The expected response status code. The default is 200. If necessary you may indicate multiple response codes separated by || (e.g. 302 || 301). Avoid this if possible as it indicates there is ambiguity in your tests or your API. Ambiguity is bad.

  • ssl: Make this request use SSL? Defaults to False. This only comes into play if the url does not provide a scheme (see Target Host for more info).

  • verbose: If True print a representation of the current request and response, including both headers and body to stdout. If set to headers or body then only the corresponding part of the request and response will be displayed. all is a synonym for True. If the output is a tty, colors will be used. See VerboseHttp for more details. Defaults to False.

  • redirects: If True automatically follow redirects. Defaults to False.

  • request_headers: A dictionary of key-value pairs representing request header names and values. These will be added to the constructed request.

  • data: A representation to pass as the body of a request. If you use this you should set content-type in request_headers to something meaningful. See Data below for more details.

  • skip: A string message which if set will cause the test to be skipped with the provided message.

  • xfail: If True expect this test to fail but run it anyway.

  • response_headers: A dictionary of key-value pairs representing expected response headers. If the value of a header is wrapped in /, it will be treated as a raw regular expression string.

  • response_strings: A sequence of string fragments expected to be in the response body.

  • response_json_paths: A dictionary of JSONPath rules paired with expected matches. Using this rule requires that the content being sent from the server is content-type application/json or is a content-type derived from JSON and thus includes +json in the content-type value.

  • poll: A dictionary of two keys:

    • count: An integer stating the number of times to attempt this test before giving up.
    • delay: A floating point number of seconds to delay between attemmpts.

    This makes it possible to poll for a resource created via an asynchronous request. Use with caution.

The response_* items are examples of Response Handlers. Additional handlers may be created by test authors for specific use cases. See Response Handlers for more information.

There are a number of magical variables that can be used to make reference to the state of a current test or the one just prior. These are replaced with real values during test processing. They are processed in the order given.

  • $SCHEME: The current scheme/protocol (usually http or https).
  • $NETLOC: The host and potentially port of the request.
  • $ENVIRON['<environment variable>']: The name of an environment variable. Its value will replace the magical variable. If the string value of the environment variable is "True" or "False" then the resulting value will be the corresponding boolean, not a string.
  • $LOCATION: The location header returned in the prior response.
  • $HEADERS['<header>']: The value of any header from the prior response.
  • $RESPONSE['<json path>']: A JSONPath query into the prior response. See JSONPath for more on formatting.

Where a single-quote character, ', is shown above you may also use a double-quote character, ", but in any given expression the same character must be used at both ends.

All of these variables may be used in all of the following fields:

  • url
  • query_parameters
  • data
  • request_headers
  • response_strings
  • response_json_paths (on the value side of the key value pair)
  • response_headers (on the value side of the key value pair)

With these variables it ought to be possible to traverse an API without any explicit statements about the URLs being used. If you need a replacement on a field that is not currently supported please raise an issue or provide a patch.

As all of these features needed to be tested in the development of gabbi itself, the gabbi tests are a good source of examples on how to use the functionality. See also Test Example for a collection of examples and the gabbi-demo tutorial.

Data

The data key has some special handing to allow for a bit more flexibility when doing a POST or PUT. If the value is not a string (that is, it is a sequence or structure) it is treated as a data structure which is turned into a JSON string. If the value is a string that begins with <@ then the rest of the string is treated as the name of a file to be loaded from the same directory as the YAML file. If the value is an undecorated string, that’s the value.

When reading from a file care should be taken to ensure that a reasonable content-type is set for the data as this will control if any encoding is done of the resulting string value. If it is text, json, xml or javascript it will be encoded to UTF-8.