webtest

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2024 License: ISC, BSD-3-Clause Imports: 11 Imported by: 0

Documentation

Overview

Package webtest implements script-based testing for web servers.

The scripts, described below, can be run against http.Handler implementations. Testing against an http.Handler makes it easier to test handlers serving multiple sites as well as scheme-based features like redirecting to HTTPS.

The test function TestHandler take a *testing.T and a glob pattern, which must match at least one file. It create a subtest of the top-level test for each script. Within each per-script subtest, it create a per-case subtest for each case in the script, making it easy to run selected cases.

Scripts

A script is a text file containing a sequence of cases, separated by blank lines. Lines beginning with # characters are ignored as comments. A case is a sequence of lines describing a request, along with checks to be applied to the response. For example, here is a trivial script:

GET /
body contains Go is an open source programming language

This script has a single case. The first line describes the request. The second line describes a single check to be applied to the response. In this case, the request is a GET of the URL /, and the response body must contain the text “Go is an open source programming language”.

Requests

Each case begins with a line starting with GET, HEAD, or POST. The argument (the remainder of the line) is the URL to be used in the request. Following this line, the request can be further customized using lines of the form

<verb> <text>

where the verb is a single space-separated word and the text is arbitrary text to the end of the line, or multiline text (described below).

The possible values for <verb> are as follows.

The verb “hint” specifies text to be printed if the test case fails, as a hint about what might be wrong.

The verbs “postbody”, “postquery”, and “posttype” customize a POST request.

For example:

POST /api
posttype application/json
postbody {"go": true}

This describes a POST request with a posted Content-Type of “application/json” and a body “{"go": true}”.

The “postquery” verb specifies a post body in the form of a sequence of key-value pairs, query-encoded and concatenated automatically as a convenience. Using “postquery” also sets the default posted Content-Type to “application/x-www-form-urlencoded”.

For example:

POST /api
postquery
	x=hello world
	y=Go & You

This stanza sends a request with post body “x=hello+world&y=Go+%26+You”. (The multiline syntax is described in detail below.)

Checks

By default, a stanza like the ones above checks only that the request succeeds in returning a response with HTTP status code 200 (OK). Additional checks are specified by more lines of the form

<value> [<key>] <op> <text>

In the example above, <value> is “body”, there is no <key>, <op> is “contains”, and <text> is “Go is an open source programming language”. Whether there is a <key> depends on the <value>; “body” does not have one.

The possible values for <value> are:

body - the full response body
code - the HTTP status code
header <key> - the value in the header line with the given key
redirect - the target of a redirect, as found in the Location header
trimbody - the response body, trimmed

If a case contains no check of “code”, then it defaults to checking that the HTTP status code is 200, as described above, with one exception: if the case contains a check of “redirect”, then the code is required to be a 30x code.

The “trimbody” value is the body with all runs of spaces and tabs reduced to single spaces, leading and trailing spaces removed on each line, and blank lines removed.

The possible operators for <op> are:

== - the value must be equal to the text
!= - the value must not be equal to the text
~  - the value must match the text interpreted as a regular expression
!~ - the value must not match the text interpreted as a regular expression
contains  - the value must contain the text as a substring
!contains - the value must not contain the text as a substring

For example:

GET /change/75944e2e3a63
hint no change redirect - hg to git mapping not registered?
code == 302
redirect contains bdb10cf
body contains bdb10cf
body !contains UA-

GET /pkg/net/http/httptrace/
body ~ Got1xxResponse.*// Go 1\.11
body ~ GotFirstResponseByte func\(\)\s*$

Multiline Texts

The <text> in a request or check line can take a multiline form, by omitting it from the original line and then specifying the text as one or more following lines, each indented by a single tab. The text is taken to be the sequence of indented lines, including the final newline, but with the leading tab removed from each.

The “postquery” example above showed the multiline syntax. Another common use is for multiline “body” checks. For example:

GET /hello
body ==
	<!DOCTYPE html>
	hello, world

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TestHandler

func TestHandler(t *testing.T, glob string, h http.Handler)

TestHandler runs the test script files matched by glob against the handler h.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL