# README
This library is on Version 0 and we won't guarantee backwards compatible API changes until we go to version 1
api-test
Simple behavioural (black box) api testing library.
In black box tests the internal structure of the app is not know by the tests. Data is input to the system and the outputs are expected to meet certain conditions.
Check the godoc here.
This library is dependency free and we intend to keep it that way
Installation
go get -u github.com/steinfletcher/api-test
Examples
Framework and library integration examples
Example | Comment |
---|---|
gin | popular martini-like web framework |
gorilla | the gorilla web toolkit |
Companion libraries
Library | Comment |
---|---|
JSONPath | JSONPath assertion addons |
Code snippets
JSON body matcher
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/user/1234").
Expect(t).
Body(`{"id": "1234", "name": "Tate"}`).
Status(http.StatusCreated).
End()
}
JSONPath
For asserting on parts of the response body JSONPath may be used. A separate module must be installed which provides these assertions - go get -u github.com/steinfletcher/api-test-jsonpath
. This is packaged separately to keep this library dependency free.
Given the response is {"a": 12345, "b": [{"key": "c", "value": "result"}]}
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/hello").
Expect(t).
Assert(jsonpath.Contains(`$.b[? @.key=="c"].value`, "result")).
End()
}
and jsonpath.Equals
checks for value equality
func TestApi(t *testing.T) {
apitest.New(handler).
Get("/hello").
Expect(t).
Assert(jsonpath.Equal(`$.a`, float64(12345))).
End()
}
Custom assert functions
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/hello").
Expect(t).
Assert(func(res *http.Response, req *http.Request) {
assert.Equal(t, http.StatusOK, res.StatusCode)
}).
End()
}
Assert cookies
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Patch("/hello").
Expect(t).
Status(http.StatusOK).
Cookies(ExpectedCookie"ABC").Value("12345")).
CookiePresent("Session-Token").
CookieNotPresent("XXX").
Cookies(
ExpectedCookie"ABC").Value("12345"),
ExpectedCookie"DEF").Value("67890")).
End()
}
Assert headers
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/hello").
Expect(t).
Status(http.StatusOK).
Headers(map[string]string{"ABC": "12345"}).
End()
}
Provide basic auth in the request
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/hello").
BasicAuth("username:password").
Expect(t).
Status(http.StatusOK).
End()
}
Provide cookies in the request
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/hello").
Cookies(ExpectedCookie"ABC").Value("12345")).
Expect(t).
Status(http.StatusOK).
End()
}
Provide headers in the request
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Delete("/hello").
Headers(map[string]string{"My-Header": "12345"}).
Expect(t).
Status(http.StatusOK).
End()
}
Provide query parameters in the request
Query
can be used in combination with QueryCollection
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/hello").
Query(map[string]string{"a": "b"}).
Expect(t).
Status(http.StatusOK).
End()
}
Provide query parameters in collection format in the request
Providing {"a": {"b", "c", "d"}
results in parameters encoded as a=b&a=c&a=d
.
QueryCollection
can be used in combination with Query
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Get("/hello").
QueryCollection(map[string][]string{"a": {"b", "c", "d"}}).
Expect(t).
Status(http.StatusOK).
End()
}
Capture the request and response data
func TestApi(t *testing.T) {
apitest.New().
Observe(func(res *http.Response, req *http.Request) {
// do something with res and req
}).
Handler(handler).
Get("/hello").
Expect(t).
Status(http.StatusOK).
End()
}
one usage for this might be debug logging to the console. The provided DumpHttp
function does this automatically
func TestApi(t *testing.T) {
apitest.New().
Observe(apitest.DumpHttp).
Handler(handler).
Post("/hello").
Body(`{"a": 12345}`).
Headers(map[string]string{"Content-Type": "application/json"}).
Expect(t).
Status(http.StatusCreated).
End()
}
Intercept the request
This is useful for mutating the request before it is sent to the system under test.
func TestApi(t *testing.T) {
apitest.New().
Handler(handler).
Intercept(func(req *http.Request) {
req.URL.RawQuery = "a[]=xxx&a[]=yyy"
}).
Get("/hello").
Expect(t).
Status(http.StatusOK).
End()
}