httpexpect
A chainable Go library for declarative, end-to-end HTTP and REST API testing.
Repository Health
Technical Analysis
httpexpect is a Go testing library for building HTTP requests and asserting on HTTP responses and JSON payloads through a fluent, chainable API built on top of net/http. Rather than writing verbose boilerplate around http.Client and manual JSON unmarshaling, tests read as a declarative chain of expectations — request construction, response assertions, and deep payload inspection all compose through the same builder.
The library supports both real HTTP round-trips and direct invocation of an http.Handler or fasthttp.RequestHandler, so tests can run without spinning up a server. Beyond core JSON/text/form assertions, it includes WebSocket testing, JSON Schema and JSONPath validation, configurable retry and redirect policies, and pluggable formatters for readable failure output via testify or the standard testing package.
What You Get
- Chainable request builder for URL paths, query params, headers, cookies, and JSON/form/multipart payloads
- Deep payload assertions for JSON objects, arrays, strings, numbers, booleans, datetimes, and durations
- WebSocket testing support built on gorilla/websocket, including message and connection-parameter inspection
- JSON Schema and JSONPath query validation for complex payload shapes
- Direct http.Handler/fasthttp.RequestHandler invocation, skipping the need to start a real server
Common Use Cases
- Writing end-to-end tests for REST APIs built with net/http, gin, echo, iris, or fasthttp
- Validating JSON response shapes and values against a JSON Schema in CI
- Testing WebSocket servers by inspecting handshake, messages, and connection state
- Asserting on redirect chains, retry behavior, and round-trip timing in HTTP clients
Under The Hood
Architecture
Every matcher struct (Array, Object, String, Number, Boolean, DateTime, Duration, Value, Cookie) wraps a shared chain (chain.go) that forms a tree mirroring the assertion call graph — enter()/leave() push and pop chain nodes for path tracking, while clone() propagates chain state into nested matcher instances so a failure on a child chain (e.g. array.Value(0).String()) automatically marks the parent chain and all its children as failed without stopping test execution. The top-level entry point (expect.go’s Expect, request.go’s Request) builds an HTTP request through a fluent builder (WithJSON, WithQuery, WithHeader, etc.), executes it against a pluggable Client interface (a real net/http.Client, or Binder/FastBinder for in-process http.Handler/fasthttp.RequestHandler invocation), and returns a Response (response.go) that exposes JSON()/Header()/Cookie() accessors, each producing a new matcher rooted in the same chain. Assertion semantics are centralized in assertion.go/assertion_validation.go as typed structs consumed by a pluggable AssertionHandler, decoupling what failed from how it’s reported (Formatter, Reporter). This is a layered, composition-heavy design: the chain abstraction touches every matcher file, but the Client/Reporter/Formatter interfaces are cleanly pluggable extension points.
Tech Stack
A pure Go module (go 1.19, module github.com/gavv/httpexpect/v2) with no runtime framework dependency — it layers on net/http and, optionally, github.com/valyala/fasthttp for handler-level testing. Dependencies are narrowly scoped utility packages: github.com/imkira/go-interpol (URL path interpolation), github.com/google/go-querystring (query encoding), github.com/ajg/form (form encoding), github.com/gorilla/websocket and github.com/fasthttp/websocket (WebSocket transports), github.com/xeipuuv/gojsonschema (JSON Schema), github.com/yalp/jsonpath (JSONPath), github.com/yudai/gojsondiff (JSON diffing on failure), github.com/sanity-io/litter (Go value pretty-printing), github.com/fatih/color/moul.io/http2curl (output formatting), and github.com/stretchr/testify for the default reporter. There is no database and no build tooling beyond go build/go test; CI runs the test matrix across Go 1.19 and Go 1.x on Linux, Windows, and macOS.
Code Quality
Every source file (array.go, object.go, request.go, chain.go, etc.) has a co-located _test.go counterpart, supplemented by an e2e/ directory that runs assertions against real httptest servers and a mocks_test.go for fake reporters/clients — an extensively tested codebase using the standard testing package plus stretchr/testify for the default reporter path. Error handling is centralized rather than ad hoc: failures flow through a typed AssertionFailure/AssertionHandler pipeline instead of being returned as plain Go errors or silently swallowed, and a chain.fail()/chain.leave() lifecycle ensures a failure short-circuits descendant assertions rather than panicking. Naming is consistent and idiomatic Go (WithX builders, IsX/ContainsX/HasX assertions), and the project enforces static analysis via a linter configuration covering govet, revive, staticcheck, exhaustive, line length, misspelling, and duplicate words, alongside CI checks across three operating systems and two Go versions.
API Design
The public API reads as a small, consistent vocabulary rather than a large surface: every matcher exposes the same rhythm of WithX (build), .JSON()/.Object()/.Array() (narrow the type), and IsX/ContainsX/HasValue (assert) — once a developer learns the pattern for one matcher, Object, Array, String, Number, Boolean, DateTime, and Duration all follow the same shape, keeping the learning curve low despite the library’s breadth. Getting started requires only a single constructor call before chaining a request and its expectations, and the package documentation plus a dedicated examples directory covering several popular web frameworks and transports meaningfully lowers the cost of adopting it inside an existing test suite. The one piece of friction is a documented “canonical form” equality semantic — structs and numeric types are normalized through an implicit JSON-like round-trip — powerful for comparing arbitrary payloads, but a source of surprise for anyone expecting exact Go type equality, and it’s the kind of behavior a newcomer has to read the package doc to discover rather than infer from the method names.
Used by 2 apps in this directory
Argo Workflows
Devops · Data Engineering
The most popular Kubernetes-native workflow engine for orchestrating containerized DAGs, ML pipelines, CI/CD, and parallel batch jobs at scale.
Cozy Stack
File Storage · Productivity
Self-hosted personal cloud platform that unifies your files, apps, and devices in one private space you fully control.