You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(provider-tck): carry results in Cucumber Messages
The emitter defined its own per-scenario result list: a four-value outcome enum,
a tag list, a reason, and a field naming which Scenario Outline row an entry came
from. All of it already exists in Cucumber Messages, which is maintained,
cross-language, schema'd, and emitted natively by cucumber-jvm. The report schema
was reshaped to reference a Messages payload rather than define one
(open-feature/spec#425); this follows it.
A run now writes two files per suite: <name>.json, the envelope, and
<name>.ndjson, the results it points at, with results.digest over the exact bytes
written.
Deleted, because Messages carries them:
scenarios[] - now TestCase/TestCaseStarted/TestStepFinished/TestCaseFinished.
the outcome enum - Cucumber's own seven statuses. The declared/not-applicable
distinction was never a property of the run: it follows from the
declaration and the scenario's tags, so it is stated once in the envelope
instead of once per scenario.
example - a pickle's astNodeIds are [scenario id, table row id], and the
row id resolves in the GherkinDocument to the cells the feature file wrote.
Four implementations were each reinventing this field by hand.
tck.assetsTree - the payload carries the executed feature Source verbatim,
which answers "did two runs ask the same questions" directly rather than by
proxy.
Two things Messages cannot carry, so they stay. The declaration is an input to
reading the results, not a summary of them. And no standard results format has a
slot for the tested subject: Messages records the runtime and the OS, not what
was being asked about.
pytest-bdd emits no Messages -- it ships the legacy Cucumber JSON format -- so
messages.py assembles the stream. Two dependencies, each doing the half it owns:
cucumber-messages, the official Python types from the protocol's own repository,
for the execution messages; gherkin-official, already a transitive dependency of
pytest-bdd, for the gherkinDocument and pickle payloads, which are used as it
produces them rather than round-tripped through another representation. The
feature files are parsed again because pytest-bdd's own dataclasses drop the AST
node ids a pickle refers to.
Step results come from pytest-bdd's step hooks rather than from the scenario's
verdict, because a stream that marked all eight steps of a scenario failed would
be saying something untrue about the seven that passed and the ones never
reached. Each test case also carries a before- and after-hook TestStep: pytest
runs three phases and only the middle one executes steps, so that is where a
capability skip's reason and a teardown failure belong. A verdict no step
accounts for -- a strict xfail that passes -- is attached to the after-hook, so
it survives a consumer computing the test case's status as the worst of its
steps.
An expected failure is still a failure in the payload. The acknowledgement moved
to the envelope's knownDeviations, declared by TckConfig.known_deviations, where
it records the gap without softening the result. TckConfig also gains
not_applicable, for a capability that cannot hold rather than one the provider
declines.
Verified locally; CI does not run on this branch, which targets the report
branch rather than main. Both suites' envelopes validate against the reshaped
schema with a Draft 2020-12 validator and their digests match; both streams
validate clean against the Cucumber Messages JSON schema at v34.2.0 (661
messages each, zero errors). The stream accounts for all 29 collected scenarios;
the five the capability gate stopped are SKIPPED for every step, none PASSED, and
the one row the SDK fails is FAILED while pytest exits zero.
Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
0 commit comments