From gomega
Writes correct synchronous Gomega assertions in Go tests: dual notation, multi-return error idiom, Succeed vs. HaveOccurred, .Error() chaining, annotation helpers, and failure-output tuning.
How this skill is triggered — by the user, by Claude, or both
Slash command
/gomega:assertionsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The core mechanics of asserting *now* (vs. polling — see `gomega:async`). Assumes a dot-import (`. "github.com/onsi/gomega"`). Narrative docs: <https://onsi.github.io/gomega/#making-assertions>. For the big picture and skill map see `gomega:overview`.
The core mechanics of asserting now (vs. polling — see gomega:async). Assumes a dot-import (. "github.com/onsi/gomega"). Narrative docs: https://onsi.github.io/gomega/#making-assertions. For the big picture and skill map see gomega:overview.
Expect(ACTUAL).To(Equal(EXPECTED)) // Expect notation
Expect(ACTUAL).NotTo(Equal(EXPECTED))
Expect(ACTUAL).ToNot(Equal(EXPECTED)) // ToNot == NotTo
Ω(ACTUAL).Should(Equal(EXPECTED)) // Ω notation (⌥z on macOS)
Ω(ACTUAL).ShouldNot(Equal(EXPECTED))
To == Should, and NotTo == ToNot == ShouldNot — pure syntactic sugar. ACTUAL (left) is anything; the matcher (right) must satisfy GomegaMatcher. Pick one notation per codebase and stay consistent. Matchers are values — see gomega:matchers.
Expect/Ω accept multiple arguments. The matcher runs against the first; the assertion fails unless every trailing argument is nil or zero-valued. This collapses Go's (value, error) pattern:
// instead of:
result, err := DoSomethingHard()
Expect(err).NotTo(HaveOccurred())
Expect(result).To(Equal("foo"))
// write:
Expect(DoSomethingHard()).To(Equal("foo")) // passes only if return is ("foo", nil)
For a function returning only error, use Succeed:
Expect(DoSomethingSimple()).To(Succeed()) // func() error
Expect(DoSomethingSimple()).NotTo(Succeed())
For an error value you already hold, use HaveOccurred:
err := DoSomethingSimple()
Expect(err).NotTo(HaveOccurred())
Expect(err).To(HaveOccurred())
Use Succeed when calling the function inline; use HaveOccurred when you have an err variable. To assert on the error's content (not just its presence), reach for MatchError and friends in gomega:matchers.
Don't use Succeed with a multi-return function. The matcher only sees the first return value; the rest are consumed by the multi-return idiom above. Expect(DoSomethingHard()).To(Succeed()) matches against the string, not the error, and Expect(DoSomethingHard()).NotTo(Succeed()) can never pass.
To assert on the trailing error of a multi-return function while ignoring the other returns, chain .Error():
Expect(MultipleReturnValuesFunc()).Error().To(HaveOccurred())
Expect(MultipleReturnValuesFunc()).Error().NotTo(HaveOccurred())
.Error() retargets the assertion at the last return value (the error). The To(HaveOccurred()) form additionally asserts that all the other returns are zero-valued; the NotTo(HaveOccurred()) form lets the other returns be anything. The plain alternative is to capture and assert manually:
_, _, _, err := MultipleReturnValuesFunc()
Expect(err).To(HaveOccurred())
Pass a format string (with fmt.Sprintf args) or a func() string after the matcher. It's printed alongside the failure message to add context:
Expect(ACTUAL).To(Equal(EXPECTED), "my annotation %d", foo)
Expect(ACTUAL).To(Equal(EXPECTED), func() string { return expensive() })
The func() string form is lazily evaluated — only called if the assertion fails — so use it for any annotation that's expensive to build.
On failure Gomega prints a recursive rendering of the objects involved, produced by the format subpackage. Tune it via package-level globals (set once, e.g. in a test helper or TestMain):
import "github.com/onsi/gomega/format"
format.MaxLength = 4000 // truncate rendered output to N chars; 0 disables truncation
format.MaxDepth = 10 // max recursion depth into nested structures
format.TruncatedDiff = true // for long strings, show only where they differ (false = full strings)
format.UseStringerRepresentation = false // true => call String()/GoString() on Stringer/GoStringer types
format.PrintContextObjects = false // true => print contents of context.Context objects
UseStringerRepresentation defaults to false on purpose: a String() method often hides fields you need to diagnose a failure. Leave it off unless you know the stringer is complete.
GomegaStringer interface. Implement GomegaString() string on a type and Gomega always uses it for that type's rendering, regardless of UseStringerRepresentation. Best practice: define it in a _test.go helper file so you don't leak it into your package's exported API.
func (w Widget) GomegaString() string { return fmt.Sprintf("Widget<%s>", w.id) }
Custom formatters. Register a format.CustomFormatter (func(value any) (string, bool)) — return (rendered, true) to handle a value, or ("", false) to pass. Custom formatters take precedence over GomegaStringer and UseStringerRepresentation, and their output is not truncated:
key := format.RegisterCustomFormatter(myFormatter)
defer format.UnregisterCustomFormatter(key)
format.Object. Reuse Gomega's renderer directly (the int is indentation depth):
fmt.Println(format.Object(theThing, 1))
Factoring assertions into a helper reduces boilerplate, but a naive helper reports failures at the line inside the helper, not the caller. Fix the reported line number with one of these.
With Ginkgo — GinkgoHelper() (recommended). Call it first thing in the helper; Ginkgo then attributes failures to the call site. It nests cleanly across multiple helper layers:
func expectComponents(te TurboEncabulator, components ...string) {
GinkgoHelper()
got, err := te.GetComponents()
Expect(err).NotTo(HaveOccurred())
Expect(got).To(ConsistOf(components))
}
Without Ginkgo — WithOffset / ExpectWithOffset. The offset is how many stack frames to skip; 1 points at the helper's caller. These are equivalent:
Expect(err).WithOffset(1).NotTo(HaveOccurred())
ExpectWithOffset(1, err).NotTo(HaveOccurred())
(Eventually/Consistently have the same WithOffset / …WithOffset forms — see gomega:async.)
Plain testing — NewWithT(t). Wrap a *testing.T to get a *WithT carrying Expect, Eventually, and Consistently. Create a fresh one per test (no global fail handler needed):
func TestFarmHasCow(t *testing.T) {
g := NewWithT(t)
f := farm.New([]string{"Cow", "Horse"})
g.Expect(f.HasCow()).To(BeTrue(), "farm should have a cow")
}
The g Gomega callback pattern. A helper can accept a Gomega and assert through it, decoupling the helper from how failures are reported:
func expectValidWidget(g Gomega, w Widget) {
g.Expect(w.ID).NotTo(BeEmpty())
g.Expect(w.Size).To(BeNumerically(">", 0))
}
g := NewWithT(t) // or the g passed into an Eventually callback
expectValidWidget(g, w)
This is the same g Gomega that Eventually(func(g Gomega) {...}) passes into polled callbacks (gomega:async) — so a g Gomega helper works in both synchronous and polled contexts. To build a Gomega wired to your own fail handler, use NewGomega(failHandler).
Don't call the global Expect/Ω inside an Eventually/Consistently callback — those failures won't be intercepted by the poller. Always assert through the passed-in g Gomega there. See gomega:async.
For richer, reusable assertions consider a real matcher instead of a helper — see gomega:custom-matchers.
npx claudepluginhub onsi/gomega --plugin gomegaExplains the Gomega matcher/assertion library for Go: Expect/Ω notation, matchers-as-values, multi-return error idiom, sync vs async assertions, and sub-library overview. Routes to specialized Gomega skills.
Provides guidance on testify for Go testing: assert vs require, core assertions, mocks, and suites. Activates when code imports github.com/stretchr/testify.
Guides writing Ginkgo specs with container/subject/setup nodes, the 'declare in container, initialize in BeforeEach' rule, and reusable test helpers. Use when writing or reviewing Ginkgo tests.