webtest

package
v0.0.0-...-633599b Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2024 License: BSD-3-Clause Imports: 13 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 or against running servers. Testing against an http.Handler makes it easier to test handlers serving multiple sites as well as scheme-based features like redirecting to HTTPS. Testing against a running server provides a more complete end-to-end test.

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

The functions CheckHandler and CheckServer are similar but do not require a *testing.T, making them suitable for use in other contexts. They run the entire script and return a multiline error summarizing any problems.

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 CheckHandler

func CheckHandler(fsys fs.FS, glob string, h http.Handler) error

CheckHandler runs the test script files in fsys matched by glob against the handler h. If any errors are encountered, CheckHandler returns an error listing the problems.

func HandlerWithCheck

func HandlerWithCheck(h http.Handler, path string, fsys fs.FS, glob string) http.Handler

HandlerWithCheck returns an http.Handler that responds to each request by running the test script files mached by glob against the handler h. If the tests pass, the returned http.Handler responds with status code 200. If they fail, it prints the details and responds with status code 503 (service unavailable).

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