Fixtures¶
Experimental
gen-cases and .testspec.yaml are experimental — an exploration of the approach. Schema, API, and behavior may change. Feedback welcome.
Alternatively, install the AI agent skills and let an AI generate cases directly from source code — no spec file required.
Fixtures are shared data values declared once at file scope, before the TestXxx function. They represent payloads, protocol constants, or any reusable Go value that multiple test cases reference.
Schema¶
fixtures:
- name: <identifier>
type: <Go type>
description: <what this fixture represents>
value: |
<Go literal — may be multiline>
Fields¶
| Field | Required | Description |
|---|---|---|
name |
yes | Go identifier for the var declaration (e.g. samplePayload, validConfig). |
type |
yes | Go type string (e.g. "[]byte", "*model.Notification", "*Config"). |
description |
yes | Human-readable description of what the fixture represents. |
value |
no | Go literal to use as the initializer. If omitted, gen-cases emits an // ai-hint: placeholder. |
Generated Output¶
With a value¶
fixtures:
- name: sampleInitiativePayload
type: "[]byte"
description: Complete, valid ZH07B sensor frame in initiative-upload mode.
value: |
[]byte{
0x42, 0x4D, // Start bytes
0x00, 0x1C, // Frame length
0x00, 0x01, // PM1.0
0x00, 0x05, // PM2.5
0x00, 0x09, // PM10
}
Generated:
// Complete, valid ZH07B sensor frame in initiative-upload mode.
var sampleInitiativePayload = []byte{
[]byte{
0x42, 0x4D, // Start bytes
0x00, 0x1C, // Frame length
0x00, 0x01, // PM1.0
0x00, 0x05, // PM2.5
0x00, 0x09, // PM10
}
}
Without a value (AI fills in)¶
fixtures:
- name: validWebhookConfig
type: "*Config"
description: >
A WebhookNotifier config pointing to a local test server at
http://localhost:8080/webhook, with a custom Header-XYZ header.
Generated:
// A WebhookNotifier config pointing to a local test server at
// http://localhost:8080/webhook, with a custom Header-XYZ header.
var validWebhookConfig = *Config{
// ai-hint: fill with the value described above
// A WebhookNotifier config pointing to a local test server at
// http://localhost:8080/webhook, with a custom Header-XYZ header.
}
Insertion Position¶
Fixtures are inserted before the TestXxx function, after any existing var/const declarations in the file.
Multiple fixtures are grouped together in the order they appear in the spec.
Idempotency¶
If a var with the same name already exists in the file (detected by AST inspection of all GenDecl nodes at file scope), the fixture is skipped. Use --force to replace it.
When to Use Fixtures¶
Use fixtures when:
- A payload or config struct is shared across multiple test cases — define it once and reference it by name.
- The value is large (e.g. a binary frame, a long JSON blob) and repeating it inline would clutter the case table.
- The value is a constant in the domain (e.g. a protocol magic byte sequence).
Do not use fixtures for values that differ per case — put those in case.fields instead.
Multiple Fixtures¶
fixtures:
- name: minimalConfig
type: "*Config"
description: Config with only required fields set.
value: "&Config{Endpoint: \"http://localhost:8080\"}"
- name: fullConfig
type: "*Config"
description: Config with all optional fields populated.
value: |
&Config{
Endpoint: "http://localhost:8080/webhook",
Headers: map[string]string{"X-API-Key": "test-key"},
Insecure: false,
}
- name: testNotification
type: "*model.Notification"
description: Standard notification used in happy-path cases.
value: |
&model.Notification{
ID: "msg-01",
Event: model.EventType("test-event"),
Data: "test-data",
}