CtrlK
BlogDocsLog inGet started
Tessl Logo

setup

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

Quality

87%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

Wiring Ginkgo into a suite

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.

1. Install the CLI and the libraries

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.

2. Bootstrap the suite

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.

3. The _test package convention — and what it forces

ginkgo 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.)

4. Dot-imports and the alternatives

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:

  • Alias the whole DSL (slight g. stutter everywhere):
    import g "github.com/onsi/ginkgo/v2"
    var _ = g.Describe("Books", func() { g.It("works", func() {}) })
  • Mix-and-match the 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.

5. Add spec files

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.

6. Third-party libraries that want a *testing.T

Matcher 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.

Where to go next

  • Authoring specs (containers, subjects, setup/cleanup, construction-time pitfalls) → ginkgo:writing-specs
  • The CLI surface (run, watch, build, randomization, multiple suites) → ginkgo:running
  • A recommended CI configurationginkgo:ci
Repository
onsi/ginkgo
Last updated
First committed

Is this your skill?

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.