What is a step definition in a scenario suite, and what binds it to a line of a scenario?
answer
- Three layers, and this is the middle
- The sentence never names a function
- Something has to match the text
- Captured fragments become arguments
- No match has its own reported state
basics
~20 sA step definition is a function holding the automation code for one scenario step. The runner matches the step's plain-language text against a pattern registered with that function, converts any captured values into arguments, and calls it.
solid answer
~50 sA scenario is written in plain language, one step per line, and executes nothing by itself. The **glue layer** sits underneath: each step definition is a function registered with the runner under a pattern or step expression. At run time the runner takes a step's text, finds the one registered pattern that matches it, converts the captured fragments into typed arguments, and invokes the function, which drives the system under test and asserts the outcome. The binding is **by text, not by name or by file** — the scenario never imports or names a function, so a definition loaded from anywhere in the glue can serve a step in any scenario. When no pattern matches, the runner reports the step as *undefined* and usually prints a suggested skeleton; when a step fails, the remaining steps of that scenario are skipped.
code
pseudocode · 10 lines# scenario line:
# When they move "Year 9 Maths" to Tuesday period 3
step("they move {string} to {word} period {int}",
function(course, day, period) {
planner.moveLesson(course, day, period)
})
# the same definition also serves:
# When they move "Year 11 Physics" to Thursday period 1go deeper
Be ready to name the three layers and say plainly that the runner matches the step's text against registered patterns. Knowing that an unmatched step is reported as undefined, not as a product bug, is usually enough at this level.
An interviewer expects the mechanics: pattern versus typed placeholder, captured fragments becoming arguments, and the fact that a mismatch in the number of captures is a wiring error. Be able to list the step outcome states, including skipped.
Show that you treat the sentence namespace as shared infrastructure. Explain how you keep definitions thin, push reusable work into a helper layer beneath them, and why branching on step text inside a definition is a defect you would reject in review.
Own the question of who governs the phrase namespace across teams. Be ready to argue when a shared glue library is worth the coordination cost and when duplicated, team-local definitions are the cheaper failure.
A scenario suite has three layers, and a step definition is the middle one. ## The three layers - **The top layer is the scenario:** a handful of plain-language lines, one step per line, arranged as context, an event, and an expected outcome. It is written to be read by people who do not read code, and it executes nothing on its own. - **The bottom layer is the system under test**, reached through some driver — a service call, an HTTP client, a repository, a UI driver. - **Between them sits the glue layer:** a library of functions, each registered with the runner under a pattern, that translate one sentence into calls on the driver and assertions on what comes back. One of those functions, together with the pattern registered for it, is a *step definition*. ## Binding is by text, not by name or location This is the point interviewers are checking. Nothing in the scenario file imports a module, names a function, or points at a file. At run time the runner walks the scenario line by line; for each line it searches every pattern registered by every glue file that was loaded, and executes the function whose pattern matches. Three consequences follow: 1. First, the sentences in a suite form a **single shared namespace**: a definition written for one team's scenario will silently serve another team's scenario that happens to phrase the step the same way. 2. Second, moving a definition between glue files changes nothing about which scenarios it serves. 3. Third, **phrasing discipline is engineering work**, not editorial polish — two sentences that mean the same thing but read differently force two definitions, and one sentence matched by two patterns is a run failure. ## Patterns and parameters Two registration styles are common: - The older one is a **regular expression** whose capture groups become the function's arguments. - The newer, more readable one is a **step expression with typed placeholders** — an integer placeholder, a quoted-string placeholder, a word placeholder — that the runner converts before calling you, so the function receives a number where the sentence held a number. Either way the number of captures must match the function's parameter list; a mismatch is a wiring error the runner reports rather than a test failure. Typed placeholders are also the mechanism that lets one definition serve many sentences that differ only by a value, which is what keeps the glue small. ## The result vocabulary A step ends in one of a small set of states, and knowing them is part of the answer. - ***Passed*** — the function returned normally. - ***Failed*** — it threw, usually from an assertion. - ***Undefined*** — no registered pattern matched; the runner reports it and normally prints a skeleton you can paste in, and a strict run treats it as a failure rather than a silent skip. - ***Ambiguous*** — more than one registered pattern matched, which is an error about the glue rather than about the product. - ***Pending*** — a definition exists but declares itself unimplemented. - ***Skipped*** — the steps after a failing step in the same scenario are not executed, because the scenario's later context can no longer be trusted. That last rule is why a scenario report shows one failure and a tail of skips rather than a cascade. ## What belongs inside a definition A step definition should be **thin**: parse nothing, branch on nothing, and translate the sentence into one or two calls on a helper or driver layer. Context steps set data up, the event step performs the action under test, and outcome steps assert against something the reader of the scenario would recognise. Anything reusable — building a user, waiting for a projection, formatting a table — belongs in the layer beneath the definitions, so that duplication accumulates in helpers rather than in the step library itself. ## A worked example In a school timetable planner, the scenario line `When they move "Year 9 Maths" to Tuesday period 3` is bound by a pattern with a quoted-string placeholder, a word placeholder, and an integer placeholder. The function receives the course name, the day, and the period number, and calls `planner.moveLesson(...)`. The same definition serves `When they move "Year 11 Physics" to Thursday period 1` without a line of new glue. Had the first definition been written with the literal sentence baked in, the second scenario would have arrived as an undefined step, someone would have pasted the suggested skeleton, and the library would have grown a near-duplicate — the exact drift this layer is designed to resist.
- If the scenario never names a function, how does the runner know which glue code to load?You tell it where the glue lives — a package, directory or module list passed on the command line or in configuration. Everything found there registers its patterns at start-up, and from then on matching is purely textual. That is also why loading two libraries that both define the same phrase produces an ambiguous match rather than a shadowing rule.
- A step in the middle of a scenario fails. What does the report show for the steps after it?They are skipped, not run and not failed. Once a step fails, the context the later steps assume is no longer established, so executing them would produce noise rather than information. Practically it means one scenario yields at most one real failure, which is why a scenario should assert one outcome rather than ten.
- Should a step definition ever contain an if-statement on the step's own text?No. Branching on the sentence means one definition is impersonating several, and the branch is invisible to the person reading the scenario. If two sentences need different behaviour, register two patterns; if they differ only by a value, capture that value as a parameter.
The scenario is a phrasebook entry and the glue layer is the phrasebook's index: the runner looks the sentence up by its wording, not by a page number the sentence carries.
saying these in an interview costs you the question
- Says the scenario file calls the glue function by name
- Thinks definitions match by position or by file order
- Believes each scenario needs its own copy of the definitions
- Calls an unmatched step a bug in the product
- Thinks the plain-language text is itself executed as code
- Puts driver setup and branching logic inside every definition