Why
The live BDD suite has grown to 12 feature files, about 2,200 lines, and more than 550 Gherkin steps. It contains roughly 147 raw command steps, 116 separate exit-zero assertions, 60 individual environment-variable checks, 14 Helm list assertions, and 18 non-empty YAML-key assertions.
Raw commands remain an important escape hatch, but repeated command and assertion plumbing now obscures the operator workflow in several features. The DSL should hide shell mechanics while keeping the selected workflow, configuration, resource names, namespaces, Kubernetes contexts, timeouts, and expected state visible.
Goals
- Make feature files easier to scan as operator workflows.
- Consolidate repeated command plumbing and assertions.
- Preserve meaningful inputs and outcomes in the Gherkin text or tables.
- Keep step handlers thin and delegate pure behavior to testable DSL helpers.
- Retain raw command steps for uncommon operations and command-specific tests.
Abstraction criteria
A new step should:
- represent one operator action or one observable outcome;
- be reused across features or replace a clearly repeated pattern;
- expose every behaviorally meaningful input;
- avoid hidden workflow branching or ambient Kubernetes context;
- report failures against the specific table row or resource; and
- preserve the existing CLI-versus-Helmfile workflow boundary.
First wave
Implement low-risk steps that remove mechanics without hiding the operation.
Example vocabulary:
When I successfully run command:
"""
make -C deploy/stacks/self-managed install HELMFILE_ENV=local-bdd
"""
Given these environment variables are set:
| name |
| NGC_API_KEY |
| SAMPLE_NGC_ORG |
| SAMPLE_NGC_TEAM |
Then these Helm releases should be deployed using context "k3d-ncp-local":
| name | namespace | revision |
| nvca-operator | nvca-operator | 1 |
Then these Kubernetes resources should not exist in namespace "monitoring" using context "k3d-ncp-local":
| kind | name |
| ServiceMonitor | nvcf-default-monitors-nvca |
| PodMonitor | nvcf-default-monitors-worker |
Second wave
After the first wave is in use, add semantic steps where the hidden portion is stable implementation plumbing rather than user intent.
Out of scope
- Opaque composite steps such as
Given the stack is installed, Given the gateway is ready, or Given a sample function is running.
- Combining control-plane and compute-plane installation into one step.
- Hiding whether installation uses
nvcf-cli, Helmfile, or a stack Makefile.
- Hiding profile selections, Helmfile values, image sources, release revisions, resource identities, namespaces, contexts, or timeouts.
- Replacing exact negative-command assertions when the exit code or error text is itself under test.
- Abstracting selective Helmfile install order or selectors in image-source tests.
- Moving destructive cleanup into step handlers or changing the existing cleanup authorization model.
- Collapsing function create, deploy, API-key generation, and invocation into one lifecycle step. Individual product-oriented steps can be evaluated in separate follow-up work if their meaningful parameters remain visible.
- Changing test coverage, supported deployment topologies, or the live-test execution policy as part of the DSL refactor.
Acceptance criteria
Why
The live BDD suite has grown to 12 feature files, about 2,200 lines, and more than 550 Gherkin steps. It contains roughly 147 raw command steps, 116 separate exit-zero assertions, 60 individual environment-variable checks, 14 Helm list assertions, and 18 non-empty YAML-key assertions.
Raw commands remain an important escape hatch, but repeated command and assertion plumbing now obscures the operator workflow in several features. The DSL should hide shell mechanics while keeping the selected workflow, configuration, resource names, namespaces, Kubernetes contexts, timeouts, and expected state visible.
Goals
Abstraction criteria
A new step should:
First wave
Implement low-risk steps that remove mechanics without hiding the operation.
When I successfully run command:for commands whose required outcome is exit code 0. Preserve the command result for later output assertions and successful-command caching. Keep the existing run-plus-exit-code form for negative and exit-code-specific cases.kubectl get -o jsonpathcommand plumbing where the resource state is the contract.Example vocabulary:
Second wave
After the first wave is in use, add semantic steps where the hidden portion is stable implementation plumbing rather than user intent.
NVCFBackendreports an explicit agent status using an explicit namespace, context, and timeout.Out of scope
Given the stack is installed,Given the gateway is ready, orGiven a sample function is running.nvcf-cli, Helmfile, or a stack Makefile.Acceptance criteria
tests/bdd/AGENTS.mdandtests/bdd/PLAN.mdwith the revised abstraction rules and new catalog entries before migrating features.go test -short ./...undertests/bddafter each migration.