From ginkgo
Wires Ginkgo into a Go package: installs CLI, bootstraps suite_test.go, handles _test package convention, dot-imports, and *testing.T interop.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ginkgo:setupThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The one-time setup. For the mental model see `ginkgo:overview`; to start authoring see `ginkgo:writing-specs`. Docs: <https://onsi.github.io/ginkgo/#getting-started>.
The one-time setup. For the mental model see ginkgo:overview; to start authoring see ginkgo:writing-specs. Docs: https://onsi.github.io/ginkgo/#getting-started.
go install github.com/onsi/ginkgo/v2/ginkgo # the `ginkgo` CLI binary → $GOBIN (put it on $PATH)
go get github.com/onsi/gomega/... # the Gomega matcher library
ginkgo version confirms the install. The CLI version must match the github.com/onsi/ginkgo/v2 version in your go.mod — re-run go install ... from the package to sync them. The current major version is v2; everything here assumes it. In CI, sidestep version drift by invoking the CLI via go run github.com/onsi/ginkgo/v2/ginkgo (→ ginkgo:ci).
On macOS, XProtect slows Ginkgo's per-package go test -c compiles dramatically — run spctl developer-mode enable-terminal and add your terminal under System Settings > Privacy & Security > Developer Tools.
From inside the package you want to test:
cd path/to/books
ginkgo bootstrap # generates books_suite_test.go
package books_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestBooks(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Books Suite")
}
What each line buys you:
func TestBooks(t *testing.T) is the single go test entry point. Call RunSpecs exactly once per process — Ginkgo errors if you call it twice (a niche multi-suite-per-process escape hatch exists via extensions/globals.Reset(), see ginkgo:running).RegisterFailHandler(Fail) is the one line of glue connecting Gomega to Ginkgo: it tells Gomega to call Ginkgo's Fail on a failed assertion. Without dot-imports this reads gomega.RegisterFailHandler(ginkgo.Fail).RunSpecs(t, "Books Suite") builds the spec tree and runs it; let it drive *testing.T for you._test package convention — and what it forcesginkgo bootstrap puts the suite in package books_test, not package books. Go specially permits a *_test package to live in the same directory as the package it tests, compiled as a separate package. The consequence: your suite has no access to books's unexported internals — it must import and exercise the external API. That's deliberate, nudging you to test behavior, not implementation. (You may use plain package books for true white-box unit tests when you need the internals.)
Ginkgo and Gomega are DSLs, so the docs dot-import both into the suite's namespace to read naturally. Recommend this strongly to the user. If they'd rather keep the global namespace clean:
g. stutter everywhere):
import g "github.com/onsi/ginkgo/v2"
var _ = g.Describe("Books", func() { g.It("works", func() {}) })
dsl subpackages — dot-import the parts you want, namespace the rest:
import (
. "github.com/onsi/ginkgo/v2/dsl/core" // containers, setup, subjects, RunSpecs, By, GinkgoT
"github.com/onsi/ginkgo/v2/dsl/decorators" // Label, Ordered, Serial, …
)
var _ = It("core dot-imported", decorators.Label("namespaced decorator"), func() {})
Available: dsl/core, dsl/decorators, dsl/reporting (ReportAfterEach, AddReportEntry, …), dsl/table (DescribeTable, Entry). They re-export from the root package — no behavioral difference, purely namespacing.ginkgo bootstrap --nodot generates a no-dot bootstrap to start from.ginkgo generate book # generates book_test.go with a top-level Describe + the books import
You can write specs directly in the suite file, but ginkgo generate <subject> scaffolds a per-file Describe in the same _test package. Now write specs → ginkgo:writing-specs.
*testing.TMatcher and mocking libraries take a *testing.T (or testing.TB). Ginkgo has no real *testing.T per spec, so pass the seam instead:
GinkgoT() returns a value implementing every *testing.T method — hand it to testify, gomock, etc.GinkgoTB() returns a testing.TB-satisfying wrapper for libraries that demand that interface (reach the inner via GinkgoTBWrapper.GinkgoT).assert.Equal(GinkgoT(), foo{}.Name(), "foo") // testify instead of Gomega
mockCtrl := gomock.NewController(GinkgoT()) // gomock; Finish() auto-registered via DeferCleanup
Two behavioral differences from real *testing.T you must know:
Error/Errorf == Fatal/Fatalf. Ginkgo failures always abort the spec immediately — there is no "log a failure and keep going."Parallel() is a no-op. Ginkgo parallelizes across processes, not in-process (→ ginkgo:parallelism).With gomock, run with --trace to get stack traces pointing at the offending call. Consider the ginkgolinter (standalone or via golangci-lint) to enforce Ginkgo/Gomega idioms.
ginkgo:writing-specsginkgo:runningginkgo:cinpx claudepluginhub onsi/ginkgo --plugin ginkgoExplains the Ginkgo mental model for writing Go tests: tree construction then running, spec independence, and node taxonomy. Use this first when working with Ginkgo.
Provides guidance on testify for Go testing: assert vs require, core assertions, mocks, and suites. Activates when code imports github.com/stretchr/testify.
Go testing patterns including table-driven tests, sub-tests, benchmarks, fuzzing, and coverage. Follows TDD methodology with idiomatic Go practices.