GoForge — Build | Test | Ship | Collaborate GoForge — Build | Test | Ship | Collaborate
v0.1.0

Propkin

Property testing that stays executable Gherkin

$ go install goforge.dev/propkin/projects/propkin@latest

Propkin adds property-based testing to authored Gherkin without creating a second test language. Existing Given, When, and Then steps remain the source of truth and continue to use the project’s existing step definitions.

The current release is v0.1.0. Propkin is authored in Go+, ships its generated Go, and is structured as a GoForge workspace.

Lossless compilation

Ordinary .feature files are valid Propkin inputs and pass through byte for byte. Extended .pfeature files add two constructs:

@propkin.id.reverse-twice
@propkin.pattern.roundtrip
Property: reversing twice yields the original list
  Given a list <xs>
  When it is reversed twice
  Then the result equals <xs>

  Examples: Boundaries and regressions
    | xs |
    | [] |

  Forall:
    | xs | list(int) |

propkin compile replaces Property: with Scenario Outline: and Forall: with a deterministic generated Examples: corpus. The output is standard Gherkin validated through the official Gherkin v42 AST and Pickle compiler, so vanilla Cucumber executes it without Propkin.

Generated .feature files and canonical manifests are committed artifacts. CI detects drift with:

propkin compile --check

Native generation and shrinking

propkin test gives the same generator declarations to a native property engine and runs each generated value through an isolated, single-row standard feature. The existing Cucumber runner and step definitions do the actual work.

  • Python: Hypothesis 6.x
  • Java: jqwik 1.9.3, pinned exactly

JavaScript is not currently a target.

Create the checked-in adapter skeleton for a configured target, then run it:

propkin bindings scaffold --target python
python3 -m pip install -r .propkin/bindings/python/requirements.txt
propkin test --target python --profile local

When a property fails, the native engine shrinks it. Propkin records the target, engine version, derived seed, replay token, minimized portable values, source digest, selected policy, and redacted runner output.

propkin replay .propkin/failures/reverse-twice-python.json
propkin promote .propkin/failures/reverse-twice-python.json

Replay refuses to run against a changed source digest. Promotion explicitly inserts the minimized values into an authored Examples: Regressions block.

Reproducible seeds

The seed precedence is explicit:

  1. --seed
  2. PROPKIN_SEED
  3. SEED
  4. the persistent seed in propkin.toml

Propkin derives a stable per-property native seed, so one property does not change merely because another property was added or reordered.

Deployed safety

Profiles grant named capability policies, and no command-line flag can expand that ceiling. External writes require a declared write effect, isolation key, setup/reset/cleanup hooks, bounded concurrency, and timeouts.

Setup runs before generation, reset runs before every generated case and every shrink attempt, and cleanup runs after execution. Secrets remain in the environment; named secret values are redacted from persisted failures.

Install

go install goforge.dev/propkin/projects/propkin@latest

Source and license