Apitest
A simple and extensible behavioural testing library for Go. You can use api test to simplify REST API, HTTP handler and e2e tests.
Install / Use
/learn @steinfletcher/ApitestREADME
apitest
A simple and extensible behavioural testing library. Supports mocking external http calls and renders sequence diagrams on completion.
In behavioural tests the internal structure of the app is not known by the tests. Data is input to the system and the outputs are expected to meet certain conditions.
Join the conversation at #apitest on https://gophers.slack.com.
<span>Logo by <a target="_blank" href="https://twitter.com/egonelbre">@egonelbre</a><span>
Note: The API for apitest is stable and complete - despite the lack of activity this repository is still actively maintained. Any new issues will be addressed. Feature requests will be considered.
Documentation
Please visit https://apitest.dev for the latest documentation.
Installation
go get -u github.com/steinfletcher/apitest
Demo

Examples
Framework and library integration examples
| Example | Comment | | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | gin | popular martini-like web framework | | graphql | using gqlgen.com to generate a graphql server | | gorilla | the gorilla web toolkit | | iris | iris web framework | | echo | High performance, extensible, minimalist Go web framework | | fiber | Express inspired web framework written in Go | | httprouter | High performance HTTP request router that scales well | | mocks | example mocking out external http calls | | sequence diagrams | generate sequence diagrams from tests. See the demo | | Ginkgo | Ginkgo BDD test framework|
Companion libraries
| Library | Comment | | ----------------------------------------------------------------------- | -----------------------------------------------| | JSONPath | JSONPath assertion addons | | CSS Selectors | CSS selector assertion addons | | PlantUML | Export sequence diagrams as plantUML | | DynamoDB | Add DynamoDB interactions to sequence diagrams |
Credits
This library was influenced by the following software packages:
- YatSpec for creating sequence diagrams from tests
- MockMVC and superagent for the concept and behavioural testing approach
- Gock for the approach to mocking HTTP services in Go
- Baloo for API design
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.StatusOK).
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/apitest-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.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.Handler(handler).
Get("/hello").
Expect(t).
Assert(jsonpath.Equal(`$.a`, float64(12345))).
End()
}
Custom assert functions
func TestApi(t *testing.T) {
apitest.Handler(handler).
Get("/hello").
Expect(t).
Assert(func(res *http.Response, req *http.Request) error {
assert.Equal(t, http.StatusOK, res.StatusCode)
return nil
}).
End()
}
Assert cookies
func TestApi(t *testing.T) {
apitest.Handler(handler).
Patch("/hello").
Expect(t).
Status(http.StatusOK).
Cookies(apitest.Cookie("ABC").Value("12345")).
CookiePresent("Session-Token").
CookieNotPresent("XXX").
Cookies(
apitest.Cookie("ABC").Value("12345"),
apitest.Cookie("DEF").Value("67890"),
).
End()
}
Assert headers
func TestApi(t *testing.T) {
apitest.Handler(handler).
Get("/hello").
Expect(t).
Status(http.StatusOK).
Headers(map[string]string{"ABC": "12345"}).
End()
}
Mocking external http calls
var getUser = apitest.NewMock().
Get("/user/12345").
RespondWith().
Body(`{"name": "jon", "id": "1234"}`).
Status(http.StatusOK).
End()
var getPreferences = apitest.NewMock().
Get("/preferences/12345").
RespondWith().
Body(`{"is_contactable": true}`).
Status(http.StatusOK).
End()
func TestApi(t *testing.T) {
apitest.New().
Mocks(getUser, getPreferences).
Handler(handler).
Get("/hello").
Expect(t).
Status(http.StatusOK).
Body(`{"name": "jon", "id": "1234"}`).
End()
}
It is possible to configure the mock for using AnyTimes feature, it allows a mock to be invoked any number of times
without failing the asserts if it is not used the expected number of times.
This is very useful in scenarios where the exact number of invocations is not known or not important.
var getUser := apitest.NewMock().
Get("http://localhost:8080").
RespondWith().
Status(http.StatusOK).
AnyTimes().
End()
Note: The AnyTimes method can be combined with other methods such as Times, but if AnyTimes is set, the Times setting will have no effect.
Generating sequence diagrams from tests
func TestApi(t *testing.T) {
apitest.New().
Report(apitest.SequenceDiagram()).
Mocks(getUser, getPreferences).
Handler(handler).
Get("/hello").
Expect(t).
Status(http.StatusOK).
Body(`{"name": "jon", "id": "1234"}`).
End()
}
It is possible to override the default storage location by passing the formatter instance Report(apitest.NewSequenceDiagramFormatter(".sequence-diagrams")).
You can bring your own formatter too if you want to produce custom output. By default a sequence diagram is rendered on a html page. See the demo
Debugging http requests and responses generated by api test and any mocks
func TestApi(t *testing.T) {
apitest.New().
Debug().
Handler(handler).
Get("/hello").
Expect(t).
Status(http.StatusOK).
End()
}
Provide basic auth in the request
func TestApi(t *testing.T) {
apitest.Handler(handler).
Get("/hello").
BasicAuth("username", "password").
Expect(t).
Status(http.StatusOK).
End()
}
Pass a custom context to the request
func TestApi(t *testing.T) {
apitest.Handler(handler).
Get("/hello").
WithContext(context.TODO()).
Expect(t).
Status(http.StatusOK).
End()
}
Provide cookies in the request
func TestApi(t *testing.T) {
apitest.Handler(handler).
Get("/hello").
Cookies(apitest.Cookie("ABC").Value("12345")).
Expect(t).
Status(http.StatusOK).
End()
}
Provide headers in the request
func TestApi(t *testing.T) {
apitest.Handler(han
Related Skills
gh-issues
335.2kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
335.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
xurl
335.2kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
frontend-design
82.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
