Gomega

Ginkgo's preferred matcher library for expressive, readable assertions in Go tests

Library
Go
vv1.44.0
2,357 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
86 /100 Excellent
Development Activity 80
Maintenance 88
Community 76
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
86 /100 Excellent
Architecture 85
Code Quality 92
Innovation 80
Learning Curve 88

Gomega is a matcher/assertion library built to pair with the Ginkgo BDD testing framework, though it works equally well with Go’s standard testing package via NewWithT. It replaces raw if got != want { t.Fatal(...) } boilerplate with a fluent Expect(actual).To(Matcher()) DSL, producing readable assertions and detailed, diff-aware failure messages out of the box.

Beyond the roughly sixty built-in matchers covering equality, collections, errors, HTTP status, panics, and more, Gomega ships a family of sub-packages that extend testing into adjacent concerns: gexec for testing built binaries and subprocesses, ghttp for stubbing HTTP servers, gbytes for asserting against streaming buffers, gstruct for matching nested structs and slices field-by-field, gleak for goroutine leak detection, gmeasure for benchmarking experiments, and gcustom for writing custom matchers without hand-rolling the full matcher interface. Eventually and Consistently provide first-class support for asynchronous and polling assertions, a common pain point in concurrent Go code.

What You Get

  • ~60 built-in matchers for equality, collections, errors, types, panics, HTTP status codes, and more, each with clear pass/fail messaging
  • Eventually/Consistently polling assertions for testing asynchronous and eventually-consistent behavior without manual retry loops
  • gstruct for precise, field-by-field matching against structs, maps, and slices, including ignoring or requiring extra fields
  • ghttp for spinning up a stub HTTP server with route/handler expectations for testing HTTP clients
  • gexec for building, running, and asserting against compiled Go binaries and external subprocesses
  • gbytes, gleak, gmeasure, and gcustom for buffer/stream assertions, goroutine leak detection, benchmarking experiments, and hand-rolled custom matchers

Common Use Cases

  • Writing BDD-style specs with Ginkgo where Gomega supplies the Expect/To assertion layer
  • Adding readable, diff-rich assertions to plain go test suites via gomega.NewWithT(t) without adopting Ginkgo at all
  • Testing asynchronous code (goroutines, channels, eventually-consistent state) with Eventually/Consistently instead of manual sleep-and-poll loops
  • Testing CLI tools and compiled binaries end-to-end with gexec, asserting on exit codes, stdout, and stderr
  • Stubbing external HTTP dependencies in integration tests with ghttp instead of a full mock server

Under The Hood

Architecture

Gomega separates a small core assertion engine from a large, flat catalog of matchers. internal/gomega.go and internal/async_assertion.go implement the actual Expect/Eventually/Consistently machinery — including the polling loop, timeout/interval handling, and fail-handler dispatch shared by both the Ginkgo-integrated Default instance and the standalone WithT wrapper — while every concrete matcher (in matchers/) is a self-contained type implementing the three-method types.GomegaMatcher interface (Match, FailureMessage, NegatedFailureMessage). This decouples “how an assertion is made and reported” from “what is being checked,” so adding a new matcher never touches the core engine, and the sub-packages (gstruct, ghttp, gexec, gbytes, gleak, gmeasure, gcustom) extend the same matcher interface into new domains rather than forking the DSL. If the GomegaMatcher interface itself changed, essentially every matcher and sub-package would need updating, but the DSL surface (gomega_dsl.go) that end users import would remain stable.

Tech Stack

Written in Go (module targets Go 1.25) with a deliberately minimal dependency footprint: github.com/google/go-cmp for deep, diff-aware comparisons, google.golang.org/protobuf to support matching protobuf messages, golang.org/x/net for network-related matcher support, and an optional but expected pairing with github.com/onsi/ginkgo/v2, the sibling BDD framework Gomega is designed to plug into (though it works standalone against testing.T). There is no build tooling beyond the Go toolchain itself — it ships as a pure library, not a service or CLI, and its own documentation site is a static Jekyll build under docs/.

Code Quality

The repository pairs almost every matcher file with a same-named _test.go file — over a hundred test files in total — and Gomega dogfoods itself, using Ginkgo and Gomega to test Gomega. CI runs a dedicated test workflow plus CodeQL static analysis on every push. Several matcher files carry // untested sections: N comments, indicating deliberate coverage tracking rather than untested code shipped silently. Naming is consistent (XyzMatcher types, NewXyzMatcher constructors), error handling favors explicit error returns from Match over panics, and public API surfaces are documented with godoc comments describing intended usage and edge cases.

What Makes It Unique

What distinguishes Gomega from a typical assertion library (like testify’s assert/require) is the breadth of its matcher ecosystem: rather than stopping at value comparisons, it extends the same fluent DSL into asynchronous polling (Eventually/Consistently with configurable timeouts and pollers), subprocess and CLI testing (gexec), stubbed HTTP servers (ghttp), streaming buffer assertions (gbytes), goroutine leak detection (gleak), and structured benchmarking (gmeasure) — plus gcustom, which lets users define new matchers as plain functions instead of implementing the full matcher interface by hand. That consistency of interface across such a wide surface area is the library’s main differentiator.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers