BDD is collaborative work on product behavior through concrete examples. The team clarifies a rule before implementation, writes understandable examples, and automates them when useful. Cucumber executes these specifications; Gherkin is the language used to write them.
These terms are distinct. A file containing Given, When, and Then does not establish that a team practices BDD. If QA alone rewrites completed technical tests in Gherkin after development, the team gains maintenance overhead while missing the main benefit: shared understanding before coding.
Begin with a conversation about the rule
Choose a small change and bring together the product owner, developer, and QA. Discuss examples and counterexamples. A free-delivery rule involves the amount threshold, eligible items, currency, applied discounts, and calculation timing.
Record uncertainties explicitly. “Is the threshold calculated before or after a coupon?” is a product question, rather than permission to choose silently in a step definition. Discovering ambiguity is already valuable, even before any scenario is automated.
Gherkin expresses behavior
Given describes relevant initial state, When an event or action, and Then an observable outcome. And continues the preceding section. A scenario should explain its rule without requiring knowledge of selectors or application internals.
“Click the green button on the right” ages quickly and is difficult for a product owner to read. “The customer places an order” retains its meaning when the UI changes. Still, do not hide behavior-defining details such as payment method or role.
A delivery specification example
Suppose the team agrees on an illustrative rule: free delivery applies from 10,000 monetary units after discounts. The example below is a specification; executing it with Cucumber requires step definitions in the chosen language and a test ordering system.
Feature: Shipping cost
Rule: The threshold is evaluated after discounts
Scenario Outline: Shipping at the threshold
Given the eligible items total after discounts is <amount>
When the customer calculates shipping
Then the shipping cost is <delivery>
Examples:
| amount | delivery |
| 9999 | 500 |
| 10000 | 0 |
| 10001 | 0 |The data and amounts are illustrative. Discussion should produce agreed cases below, at, and above the boundary. Also check coupons, excluded products, and unsupported regions where these belong to actual requirements.
Connecting text to code
A step definition maps step text to executable code that prepares state, performs an action, or checks a result. Delegate details to API clients or interface objects so the step remains a clear boundary between specification and mechanism.
Avoid calling one step definition from another as an ordinary function. Extract shared logic beneath the step layer. Otherwise, text-to-code relationships become difficult to trace, and wording changes may affect unrelated scenarios.
Choosing the automation level
A behavioral specification does not require a browser. Delivery calculations can be checked through a domain service or API where the rule lives. A small end-to-end suite can separately confirm that users can see and use the result.
The level must match the scenario's promise. If Then says the customer sees free delivery, a calculation-function check alone is insufficient. If the scenario concerns only a pricing rule, a detailed browser matrix adds cost and distracts from the examples' purpose.
Scenario Outlines and tables
A Scenario Outline executes the same scenario for several Examples rows. Use it when data changes while the rule and actions stay the same. A table should not hide complex conditions or dozens of unrelated business situations.
A Data Table inside a step supplies structured data to one execution, such as cart contents. This is a different mechanism. Choose the representation easiest for discussion participants to read, with clear parameter names and units.
State and isolation
Each scenario needs known initial conditions. A random order left over from yesterday makes a specification irreproducible. Setup should create its own data and return identifiers; cleanup must not remove records belonging to parallel runs.
Background suits shared meaningful context, but lengthy hidden setup impairs readability. Include only what helps explain every scenario. Let the chosen runner handle technical connection setup and resource cleanup.
Maintaining living documentation
Discuss scenarios when rules change and execute them frequently enough to remain useful. Requirement links and clear ownership distinguish changed expectations from defects. Remove or rewrite old examples alongside the product.
A useful scenario lets a team member explain the rule and understand what a failure means. If only step-definition authors read it, reconsider language, detail, and whether this area needs Gherkin at all.
During review, ask someone who did not implement the scenario to explain why each example exists. Combine examples of the same rule if they add no distinct risk. If roles or conditions differ, expose that distinction in the text instead of hiding it in technical setup.
Common mistakes
Typical problems include scenarios with dozens of actions, technical steps replacing behavioral examples, ambiguous regular expressions, and several differently worded steps with identical meaning. A generic step such as “the system works correctly” provides no observable expectation.
Feature-file count does not measure BDD maturity. Automating every formulation can make discussion more expensive. Some exploratory questions first need conversation and a prototype before becoming stable examples.
Key takeaways for QA
BDD prevents misunderstandings, while automation keeps agreed examples verifiable. Cucumber and Gherkin support this when the team shares language and ownership of rules.
Start with one small story: discuss boundaries, record a few clear examples, and choose a sufficient execution level. Evaluate whether requirements became clearer and investigations faster. That matters more than mechanically rewriting every test as Given–When–Then.