Home
cd ../playbooks
Developer ToolsIntermediate

Ginkgo Table and Dynamic Specs

Parameterize and generate Ginkgo test specs correctly — DescribeTable/Entry, the four ways to name an entry, DescribeTableSubtree for multi-It rows, reusable entry sets, and the one gotcha (Entry params evaluate at construction time, not BeforeEach time) that causes most table-spec bugs.

5 minutes
By onsi (Ginkgo)Source
#ginkgo#gomega#golang#testing#table-driven-tests#go-testing

A DescribeTable entry that reads shelf["Les Miserables"] looks correct and compiles fine — but it reads a nil map, because Ginkgo evaluates every Entry argument when the test tree is built, before a single BeforeEach has run, and that one timing fact breaks more table-driven Go tests than any other Ginkgo quirk.

Who it's for: Go developers writing table-driven tests with Ginkgo and Gomega, teams migrating from repetitive It blocks to DescribeTable, anyone debugging a table spec where an Entry sees a nil or zero-value variable, engineers extracting shared It blocks across Contexts into reusable closures

Example

"Why does my DescribeTable entry get a nil pointer even though BeforeEach sets it up?" → The construction-time-vs-run-time explanation with a wrong/right code pair, plus the struct-per-row pattern for tables with many parameters and DescribeTableSubtree for entries that need multiple It blocks each

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-table-and-dynamic-specs
# Ginkgo Table and Dynamic Specs

Parameterize and generate Go test specs with Ginkgo's `DescribeTable`/`Entry` DSL and the idioms for generating specs from loops and data. All of it is syntactic sugar that runs during the tree-construction phase, before any spec actually runs — the gotchas below all follow from that one fact.

Prefer `DescribeTable`/`DescribeTableSubtree` with shared configuration over multiple repeated `It`s.

## DescribeTable + Entry

`DescribeTable(desc, specFunc, ...Entry)` generates one container holding one `It` per `Entry`. `Entry(desc, params...)`'s params are passed to `specFunc` at run time and must match `specFunc`'s signature — you get a clear runtime message if they don't.

```go
DescribeTable("Extracting the author's first and last name",

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 focused reference for Ginkgo's table-driven and dynamically generated spec idioms, anchored on the one fact that explains every gotcha: DescribeTable, Entry, and loop-generated specs are all syntactic sugar that runs during Ginkgo's tree-construction phase, before any BeforeEach or spec body executes. Covers DescribeTable/Entry syntax, the four ways to name or auto-name an entry, decorating entries with the same decorators as any other node, DescribeTableSubtree for entries that need multiple Its and their own setup, the struct-per-row pattern for tables with many parameters, reusable []TableEntry slices shared across tables, and the correct place to load fixture data that determines spec structure (TestXxx before RunSpecs, never BeforeSuite).

The centerpiece is the construction-time-vs-run-time distinction: an Entry's arguments are evaluated when the tree is built, so an entry that tries to read a BeforeEach-initialized variable silently gets the zero value — a nil map or pointer — instead of an error. The fix (pass a key, dereference inside the spec closure) and the same principle applied to shared-behavior closures across Contexts round out the reference.


Quick Start

Step 1: Create a Project Folder

mkdir ginkgo-tables && cd ginkgo-tables

Step 2: Download the Template

Click Download above, then:

mv ~/Downloads/CLAUDE.md ./

Step 3: Write Table Specs

claude

Point Claude at a Go test file using Ginkgo and ask it to convert repetitive It blocks into a DescribeTable, or to debug a table spec that's seeing unexpected zero values. It will apply the construction-time rule correctly and pick the right entry-naming and row-sharing pattern for the situation.


Tips & Best Practices

  • If an Entry needs data that only exists after setup runs, pass a lookup key instead of the value itself, and resolve it inside the spec closure — the fix is almost always this shape.
  • Switch from positional Entry(nil, 12, 1.2, 8.5, 11, 2783) arguments to a named struct the moment a table grows past two or three parameters; unreadable entries are the most common table-spec code-review complaint.
  • Use DescribeTableSubtree instead of DescribeTable the moment one row needs more than one assertion or its own BeforeEach — trying to cram multiple concerns into a single It per entry is a sign you want the subtree form.

Limitations

  • Covers table and dynamic specs specifically — general Ginkgo authoring (container/subject/setup nodes, JustBeforeEach, GinkgoHelper()) is a separate topic.
  • Assumes familiarity with Ginkgo's two-phase construction/run model; if that model itself is unfamiliar, read Ginkgo's own overview docs first.
  • Code samples target Ginkgo's Go DSL — the concepts (deferred evaluation, construction- vs. run-time data) don't transfer directly to other BDD frameworks with different execution models.

$Related Playbooks

Developer Tools

Ginkgo Timeouts and Async Testing

Make Ginkgo specs interruptible and test asynchronous behavior correctly — SpecContext cancellation, NodeTimeout/SpecTimeout/GracePeriod, Eventually/Consistently with proper context propagation, and the two goroutine rules (GinkgoRecover, poll-don't-block) that prevent one failed assertion from crashing an entire Go test suite.

5 minutes
Intermediate
Developer Tools

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
Beginner
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

Browse all Developer Tools playbooks →