Testing¶
Keryx follows the GTB way: unit-test the deterministic core directly, drive the user-facing workflows through Gherkin scenarios, and fake every external backend behind its interface. This page covers the godog BDD end-to-end suite — the top of that pyramid.
Layers¶
| Layer | What it covers | How to run |
|---|---|---|
| Unit | The pure core — timing maths, storyboard validation, wrapping, theme/social/workspace logic, path resolution. Providers and ffmpeg are mocked. | just test |
| Race | The same suite under the race detector. | just test-race |
| Integration | Real ElevenLabs / Gemini / ffmpeg. Env-gated (INT_TEST=1), *_integration_test.go. |
just test-integration |
| E2E (BDD) | The CLI authoring loop against a compiled binary, end to end. Env-gated (INT_TEST_E2E=1). |
just test-e2e |
just ci runs unit → race → lint → e2e.
The BDD harness¶
The end-to-end suite proves the contracts in
spec 0002 §1 hold against the real
keryx binary, not in-process handlers.
- Features live in
features/as plain Gherkin.authoring.featurewalks the deterministic inject path: seed the catalog → create a workspace → inject a storyboard → render a silent reel → compose and review social copy. - Steps live in
test/e2e/steps/(packagesteps). They build./cmd/keryxonce per run and execute it in an isolated throwaway project — a temp dir withHOMEandXDG_CONFIG_HOMEpointed at it — so each scenario gets its own config andreels/workspace and never touches your real config. - No network, no LLM. Scenarios exercise the deterministic inject half of
the dual-mode commands (
storyboard draft --inject,social set), never the chat-provider half. That keeps the gate fast and hermetic.
Tags¶
The render scenario is tagged @ffmpeg. When ffmpeg is not on PATH (as in
the CI build image), the harness filters those scenarios out so the deterministic
CLI scenarios still gate; locally, with ffmpeg installed, the full reel render
runs and the output .mp4 is asserted to exist.
Writing a scenario¶
Reuse the existing steps where you can — they are intentionally generic:
Given a fresh keryx project
When I run "reel new my-post"
Then it succeeds
And the output contains "created reels/my-post"
I run "<args>" shells the binary with --ci prepended and honours
double-quoted flag values (so --text "two words" survives). it succeeds /
it fails assert the exit code; the output contains matches combined
stdout+stderr; the file "<path>" exists checks a path under the project dir.
Add a new sc.Step(...) in steps_test.go only when an existing step can't
express the assertion.
CI¶
The phpboyscout/cicd/go-test component runs the e2e gate when
enable_e2e: true (set in .gitlab-ci.yml).
A new user-facing command or workflow is not done until it ships a scenario —
this is part of the Definition of Done alongside green just ci and its docs
page.