Wire Ginkgo into a Go package — install the ginkgo CLI and Ginkgo+Gomega, ginkgo bootstrap to generate the suite_test.go (TestXxx/RegisterFailHandler(Fail)/RunSpecs), the package xxx_test convention, dot-import alternatives (aliased import, dsl/* subpackages, --nodot), ginkgo generate, and *testing.T interop via GinkgoT()/GinkgoTB() for testify/gomock. Use when first adding Ginkgo to a repo, bootstrapping a suite, or integrating a *testing.T-based library.
72
87%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
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 libraryginkgo 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.gopackage 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() {})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 importYou 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 DeferCleanupTwo 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:cif2d0f65
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.