In a Karate feature file, what does a step that begins with a bare `*` — such as `* def id = 5` — mean, and what changes if you write `Given`, `When` or `Then` in front of it instead?
answer
- Not one prefix but six
- A label, not a binding
- Think bullet point, not sentence grammar
- Nothing in dispatch reads it
basics
~20 sNothing changes. Karate accepts six step prefixes - the bare asterisk plus Given, When, Then, And and But - and treats all six identically. The prefix never reaches the code that decides what a step does; it is read back only afterwards, by the report and the rest of the output.
solid answer
~1 minNothing changes; the two steps run identically. Karate's own parser accepts exactly six step prefixes - `*`, `Given`, `When`, `Then`, `And` and `But` - and produces the same kind of prefix token for every one of them. Whichever you write is stored on the parsed step as its prefix. Nothing in dispatch reads it - the code that decides what a step does is handed the step text with the prefix already removed - but several things downstream do: the rendered report, the `keyword` field of Karate's Cucumber-JSON output, the JUnit-XML output, the text of a step-failure message, and the copy made when a `Scenario Outline` row is expanded. On Karate 2.x it also reaches the info map handed to a `configure onStepFailure` hook, where your own JavaScript can read it mid-run. So the prefix is inert in dispatch, not unread. What a step *does* is decided by the first token after the prefix - here `def`. So `* def id = 5`, `Given def id = 5` and `Then def id = 5` are one and the same step with three different labels. The bare `*` is the idiomatic form and outnumbers the word prefixes several times over in Karate's own feature files.
code
gherkin · 8 linesFeature: the step prefix is a label
Scenario: three ways to write one step
* def id = 5
Given def id = 5
Then def id = 5
# all three ran the same code; only the label in the output differs
* match id == 5go deeper
Recall that Karate accepts six step prefixes and that the bare asterisk is one of them. Being able to say the prefix changes nothing about execution is the whole answer at this level.
Explain the split: the prefix is parsed onto the step and read back only downstream of execution - by the report, the JSON and a failure message - while execution itself reads the first token after it. Naming that boundary is what separates you from a memorised answer.
In review, treat the prefix as documentation. It can never change which code runs, so an argument about Given versus asterisk is time not spent on the keyword that actually runs. Know that it is not quite invisible either: on Karate 1.x, with showAllSteps turned off, asterisk steps are hidden from the report, so a team that reads reports should know which prefix it standardised on.
Karate bought its conciseness by making the Gherkin prefix decorative. Decide whether your organisation still wants the words for readers outside the team, knowing the engine never dispatches on them and will never enforce the convention for you.
## Six prefixes, one meaning Karate parses `.feature` files with a parser of its own rather than borrowing a Gherkin library, and that parser accepts exactly six step prefixes: - `*` — the bare asterisk, the neutral "bullet point" form - `Given` - `When` - `Then` - `And` - `But` All six are one alternation in the grammar: whichever you write, the parser emits the same kind of step-prefix token and hands the rest of the line to the same code. `* def id = 5`, `Given def id = 5` and `Then def id = 5` are therefore not three variants of a step. They are one step wearing three different labels. (`But` is accepted and is used exactly zero times in Karate's own feature files.) ## Where the prefix actually goes A parsed step carries the prefix and the rest of the line as separate fields. Trace who reads the prefix back and the list is longer than "the report" — but every reader on it sits *after* the decision about what to run: - the report output, where the step is rendered as prefix plus step text; - the `keyword` field of Karate's Cucumber-JSON output, so that tools expecting that format see something familiar — a step written with `*` reports its keyword as an asterisk; - the JUnit-XML output, which writes the same prefix-plus-text line; - the text of a step-failure message, which echoes the failing step back to you with its prefix attached; - the copy that is made when a `Scenario Outline` row is expanded into a concrete scenario, so the label survives into the generated step; - on Karate 2.x, the info map handed to a `configure onStepFailure` hook — which is not an output writer at all, so your own JavaScript can read the prefix while the run is going on; - on Karate 1.x, report *visibility*: with `configure report = { showAllSteps: false }` a `*` step that is not a `print` is dropped from the report entirely, while an otherwise identical `Given` step is kept. What none of them is, is dispatch. The code that decides what a step *does* is handed the step text with the prefix already removed, so the prefix can never change which code runs — only what you see afterwards. "Purely cosmetic" is therefore a slightly stronger claim than the one that is always safe: the prefix never selects behaviour. ## What decides the step, then The first token after the prefix. In `* def id = 5` that token is `def`, and `def` is one of Karate's built-in keywords, so the built-in variable-assignment behaviour runs. Swap the prefix for `Then` and `def` is still the first token after it, so the same behaviour runs. The prefix cannot influence this because it is never consulted. This is why the `*` form exists and why it dominates real Karate code. There is no step-definition layer for `Given` to introduce and no `Then` for an assertion to bind to: every step is a call into a fixed built-in vocabulary. Karate reuses Gherkin's *syntax*, and the prefix is the part of that syntax with nothing left to do. | what you write | changes which code runs | changes the output | |---|---|---| | `* def id = 5` | no | yes — renders with `*` | | `Given def id = 5` | no | yes — renders with `Given` | | `Then def id = 5` | no | yes — renders with `Then` | | `* status 200` | no | yes — renders with `*` | The middle column is the one that never moves. The right-hand one is *usually* just the glyph, but not always: on Karate 1.x with `configure report = { showAllSteps: false }`, the `*` rows above are not rendered with an asterisk — they are not rendered at all, while the `Given` and `Then` rows still are. That is a different report, not a different label. ## Choosing between them Because the choice is free, it is purely an editorial one, and two conventions are common: 1. **Asterisks everywhere.** Reads as a script, which is what a Karate feature honestly is. It removes the temptation to argue about whether a `path` step is arrangement or action. 2. **Words on the HTTP shape, asterisks on the plumbing.** `Given` for `url`/`path`/`header`, `When` for `method`, `Then` for `status`/`match`, and `*` for `def`, `call`, `print` and configuration. This keeps the report readable to someone outside the team. Whichever you pick, pick one per repository and enforce it in review, because the engine will not. A mixed file is not broken, only noisy. ## Two traps - **The asterisk is not a wildcard.** It is not a repetition marker, not a glob and not a "run this for every row" instruction. It is a bullet point. - **The prefix is not optional.** Every step line needs one of the six; the parser reads a step as a prefix followed by the rest of the line. The asterisk exists so there is always a neutral one available — most obviously inside a `Background`, where "given/when/then" has no narrative meaning at all. ## What this does NOT mean Two conclusions people draw from "the prefix binds to nothing" are wrong, and both show up in interviews: - **It does not mean the prefix is thrown away.** It survives parsing, it survives `Scenario Outline` expansion into each generated row, and it reaches the report, the JSON, the JUnit XML and any failure message. It is inert in dispatch, not absent. - **It does not mean Karate is loose about step structure.** The step grammar is strict: one of six prefixes, then a keyword from a closed built-in set, then that keyword's expression. The freedom is confined to the label; everything after it is checked. ## How to answer this in an interview Say three things and stop: Karate accepts six prefixes; the prefix never reaches the code that decides what a step does; the first token *after* the prefix is what selects behaviour. If the interviewer pushes, add the observable consequence — the only way to tell `Given def id = 5` from `* def id = 5` after a run is to look at the output, never at what the step did. If they push again, the honest framing is that Karate kept Gherkin's shape and dropped its binding: the prefix is the visible fossil of a layer that is not there.
- Is the prefix optional - can a step line in a Karate feature file start straight with `def`?No. The parser reads a step as a prefix followed by the rest of the line, so every step needs one of the six. The bare `*` exists precisely so a neutral one is always available - most obviously inside a `Background`, where a given/when/then reading has no narrative meaning.
- If the prefix binds to nothing, is there any way to tell after a run which prefix a step used?Yes - in the output, and in one place that is not output. The prefix is written into the rendered report alongside the step text, into the `keyword` field of Karate's Cucumber-JSON output (where a step written with the bare asterisk shows as an asterisk), into the JUnit-XML output, and into the text of a step-failure message. On Karate 2.x it is also handed to a `configure onStepFailure` hook, so your own JavaScript can read it during the run. What no version does is let it change which code ran.
The prefix is the bullet glyph in a bulleted list. Swapping a dash for a dot changes how the list is rendered, never what the step does.
saying these in an interview costs you the question
- Thinks Given, When and Then select different step definitions
- Believes swapping Then for Given changes which code runs
- Says the bare asterisk is legal only inside Background
- Claims Karate enforces Given-When-Then ordering and fails otherwise
- Treats the asterisk as a wildcard or repeat marker