Home
cd ../playbooks
Developer ToolsBeginner

Writing Ginkgo Specs

Author correct Ginkgo specs — container vs. subject vs. setup nodes, the declare-in-container/initialize-in-setup rule that prevents the most common Ginkgo bug, JustBeforeEach for separating creation from configuration, DeferCleanup for restore-not-clear teardown, and GinkgoHelper() for failure locations that point at the caller instead of the helper.

5 minutes
By onsi (Ginkgo)Source
#ginkgo#gomega#golang#testing#bdd-testing#go-testing

A Ginkgo spec that initializes a shared variable directly inside a Describe block instead of in BeforeEach looks fine and often passes — until specs run in a different random order and start mutating each other's state, because that variable was only ever set once, at test-tree construction time, not fresh per spec.

Who it's for: Go developers new to Ginkgo/Gomega BDD-style testing, teams reviewing Ginkgo specs for the declare-vs-initialize mistake, engineers extracting test helpers who want failure messages to point at the right line, anyone deciding between BeforeEach and JustBeforeEach for shared test setup

Example

"Why do my Ginkgo tests fail only when run in random order?" → The construction-time-vs-run-time explanation for why a variable initialized directly in a Describe body gets shared and mutated across specs, the fix (declare in the container, initialize in BeforeEach), and when to reach for JustBeforeEach instead to separate input configuration from object creation

CLAUDE.md Template

New here? 3-minute setup guide → | Already set up? Copy the template below.

Or install from your terminal:
npx ccplaybooks add ginkgo-writing-specs
# Writing Ginkgo Specs

Author good Ginkgo specs: container nodes (`Describe`/`Context`/`When`), subject nodes (`It`/`Specify`), setup/cleanup nodes (`BeforeEach`, `JustBeforeEach`, `AfterEach`, `DeferCleanup`, `BeforeSuite`/`AfterSuite`), the "declare in container, initialize in setup" rule, separating creation from configuration, reusable test helpers with `GinkgoHelper()`, and `By`/`GinkgoWriter` output.

## The Shape of a Spec

```go
var _ = Describe("Books", func() {
	var book *books.Book          // declare here...

	BeforeEach(func() {
		book = &books.Book{        // ...initialize here, fresh per spec

Get new playbooks like this one

One email a week with new Claude Code workflows. Free, like everything here.

No spam. Unsubscribe anytime.

README.md

What This Does

A grounded reference for writing correct Ginkgo specs, built around Ginkgo's two-phase model: container bodies (Describe/Context/When) run once at tree-construction time, while setup and subject nodes (BeforeEach, It) run fresh per spec. That distinction produces the single rule that prevents most Ginkgo bugs — declare shared variables in the container, initialize them in BeforeEach — and explains why assertions and expensive work never belong directly inside a container body.

It covers the full setup/cleanup node table and their execution order (BeforeEach outer-to-inner, AfterEach inner-to-out, JustBeforeEach after all BeforeEaches for separating input configuration from object creation), DeferCleanup's LIFO teardown registered next to the setup it undoes (restore original state, don't just clear it), GinkgoWriter and By for output that only surfaces on failure, and GinkgoHelper()/GinkgoHelperGo for keeping failure locations pointed at the calling spec instead of buried inside a shared test helper.


Quick Start

Step 1: Create a Project Folder

mkdir ginkgo-specs && cd ginkgo-specs

Step 2: Download the Template

Click Download above, then:

mv ~/Downloads/CLAUDE.md ./

Step 3: Write or Review Specs

claude

Point Claude at a new or existing Ginkgo test file and ask it to write specs, review them for the declare/initialize mistake, or extract a shared assertion into a GinkgoHelper()-marked function. It will apply the container/setup distinction and the correct cleanup and helper patterns.


Tips & Best Practices

  • Randomize spec execution order locally (ginkgo --randomize-all) — it's the fastest way to surface a variable that was wrongly initialized in a container body instead of BeforeEach.
  • Reach for JustBeforeEach only when several Contexts need to override just one input before a shared creation step; overusing it produces hard-to-follow nesting.
  • Mark every helper in a call chain with GinkgoHelper(), not just the outermost one — it composes, and a single unmarked frame in the middle breaks the failure-location chain for everything above it.

Limitations

  • Covers spec authoring specifically — table-driven specs and asynchronous/timeout testing are separate, related topics.
  • The declare/initialize rule and node-ordering table are specific to Ginkgo's construction/run-phase model; they don't map directly onto Go's standard testing package or other test frameworks.
  • Assumes Ginkgo and Gomega are already wired into the test suite (RegisterFailHandler, RunSpecs) — initial suite bootstrap is out of scope.

$Related Playbooks

Developer Tools

Git Conflict Resolution Framework

A plan-first framework for resolving Git merge conflicts by combining both branches' intent instead of blindly picking a side — categorized resolution patterns for imports, tests, generated files, configs, code logic, and struct definitions, with a mandatory approval step before any file is touched.

5 minutes
Intermediate
Developer Tools

Git Commit & PR Automation

Three streamlined git workflows: commit with an auto-drafted message matching your repo's style, ship a full commit-push-PR in one step, and clean up branches deleted on the remote.

5 minutes
Beginner
Developer Tools

Hookify Guardrails

Create custom Claude Code guardrails with lightweight markdown rule files instead of hand-editing hooks.json — pattern matching, no restart required, rules live-load on the next tool call.

5 minutes
Beginner
Developer Tools

GEO Schema: Structured Data for AI Citation

Audit and generate schema.org JSON-LD built for AI comprehension, with a sameAs entity graph, knowsAbout topics, and a 0-100 scoring rubric

10 minutes
Intermediate
Developer Tools

GEO Technical SEO Audit: 8 Categories, 100 Points

A scored technical audit covering crawlability, indexability, security, Core Web Vitals, and the server-side rendering check that decides whether AI crawlers see your content at all

15 minutes
Advanced
Developer Tools

GEO Toolkit Updater

Pull the latest geo-seo-claude skills, agents, scripts, and schema templates from upstream, with a diff summary before anything is overwritten

5 minutes
Beginner
Developer Tools

GPT Taste Skill: Strict Anti-Slop UI Rules

A stricter, more deterministic anti-slop frontend ruleset with GSAP motion patterns, despite the GPT-oriented name it works as a standard CLAUDE.md in Claude Code

5 minutes
Intermediate
Developer Tools

GitHub Contributor

A phase-based playbook for shipping pull requests maintainers actually merge — discovery, CONTRIBUTING compliance, PR-size checks, minimal diffs, and post-submission interaction.

20 minutes
Intermediate
Developer Tools

GitHub Operations

Comprehensive GitHub operations using the gh CLI and REST/GraphQL APIs — PRs, issues, repositories, workflows, and bulk operations across public and Enterprise GitHub.

10 minutes
Intermediate
Developer Tools

i18n Expert

Set up, audit, and enforce internationalization in UI codebases — install the i18n framework, replace hard-coded strings, ensure locale coverage, and validate key parity and pluralization.

20 minutes
Intermediate
Developer Tools

Idea-to-Design Brainstorming Gate

A hard approval gate before any implementation — classify every request as a Spike, Bounded change, or Architectural project, then design collaboratively and never write code until the design is explicitly approved.

5 minutes
Intermediate
Developer Tools

Improve: Audit Your Codebase and Write the Plans

Turns Claude into a read-only senior advisor that audits a repo, ranks findings by leverage, and writes self-contained implementation plans to disk for cheaper models to execute

10 minutes
Intermediate

Browse all Developer Tools playbooks →