Configures and runs Ginkgo - Go BDD test framework with `Describe` / `Context` / `It` nesting; `BeforeEach` / `AfterEach` / `JustBeforeEach` / `JustAfterEach` lifecycle; Gomega matchers DSL (`Expect(actual).To(Equal(expected))`); parallel execution via `-p`; focus (`F` prefix) + skip (`P` prefix); `DescribeTable` + `Entry` for parametrized tests; `ginkgo` CLI tool. Use when working with Go on a BDD-style test suite (Kubernetes-ecosystem standard).
80
100%
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
Ginkgo is a Go BDD framework. The Kubernetes ecosystem standardized on Ginkgo + Gomega for its test suites.
For non-BDD Go projects, go-test (stdlib)
is the idiomatic choice. Ginkgo fits when:
Describe/Context/It
reads better than flat func TestXxx.go install github.com/onsi/ginkgo/v2/ginkgo@latest
go get github.com/onsi/ginkgo/v2
go get github.com/onsi/gomega/...In the package to test:
ginkgo bootstrap # creates <package>_suite_test.go
ginkgo generate calc # creates calc_test.go template<package>_suite_test.go:
package calc_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestCalc(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Calc Suite")
}package calc_test
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"myproject/calc"
)
var _ = Describe("Calculator", func() {
var c *calc.Calculator
BeforeEach(func() {
c = calc.New()
})
Describe("Add", func() {
Context("with positive numbers", func() {
It("adds correctly", func() {
Expect(c.Add(1, 2)).To(Equal(3))
})
})
Context("with overflow", func() {
It("returns error", func() {
_, err := c.AddSafe(math.MaxInt, 1)
Expect(err).To(HaveOccurred())
})
})
})
})The var _ = Describe(...) pattern registers the spec at package
init time. Ginkgo discovers + runs registered specs.
Per gn-docs:
BeforeSuite(func() { /* once before all specs */ })
AfterSuite(func() { /* once after all specs */ })
BeforeEach(func() { /* before each It in scope */ })
AfterEach(func() { /* after each It in scope */ })
JustBeforeEach(func() { /* after BeforeEach but before It */ })
JustAfterEach(func() { /* after It but before AfterEach */ })Hooks nest with Describe/Context - BeforeEach in nested
Context runs in addition to outer BeforeEach.
Expect(value).To(Equal(expected))
Expect(err).To(HaveOccurred())
Expect(list).To(HaveLen(3))
Expect(value).To(BeNumerically(">", 0))
Eventually(func() bool { return ready() }).Should(BeTrue())Eventually polls until the condition holds; Consistently polls
to verify it stays true. Useful for async + concurrent code.
Full matcher DSL (strings, collections, numeric tolerance, panics, errors, channels): references/gomega.md.
DescribeTable("Add",
func(a, b, expected int) {
Expect(calc.Add(a, b)).To(Equal(expected))
},
Entry("positive", 1, 2, 3),
Entry("zero", 0, 0, 0),
Entry("negative", -1, 1, 0),
Entry("large", 100, 200, 300),
)DescribeTable is Ginkgo's parametrize equivalent of pytest's
@pytest.mark.parametrize or JUnit's @ParameterizedTest.
FDescribe("focused", func() { ... }) // F prefix: only this runs
PDescribe("pending", func() { ... }) // P prefix: skippedSame for FContext/PContext, FIt/PIt, FDescribeTable/PDescribeTable.
CI gating: lint forbid F prefixes via ginkgo --no-focus (errors
if any focused specs in suite).
ginkgo -p ./... # parallel; uses CPU count
ginkgo -procs=4 ./... # explicit process countEach parallel process runs a subset of specs. Tests must be independent - shared state breaks parallel runs.
ginkgo -p --cover --coverprofile=coverage.out --no-focus -r--no-focus fails the build if any F-prefix specs exist (catches
debug-leftover focus).
Full GitHub Actions workflow (coverage upload, JUnit XML report): references/ci.md.
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Use Ginkgo for non-BDD codebase | Verbose vs stdlib testing | Use go-test for non-BDD |
Commit FDescribe / FIt accidentally | Suite runs only focused specs | --no-focus flag (Step 9) |
Skip Eventually for async assertions | Sleep-based polls are flaky | Use Eventually/Consistently (Step 5) |
| Heavy nesting (5+ levels) | Test setup hard to reason about | Flatten with Describe+It |
Use . import for both Ginkgo + Gomega without thinking | Namespace pollution | Standard convention; document |
testing - pays off only when tests benefit
from hierarchical grouping.go-test,
cargo-test,
rstest-tests - sister toolstest-code-conventions (qa-test-review)