Drizz raises $2.7M in seed funding
Featured on Forbes
Drizz raises $2.7M in seed funding
Featured on Forbes
Logo
Schedule a demo
Blog page
>
Gherkin Syntax: Every Keyword Explained With Mobile Testing Examples

Gherkin Syntax: Every Keyword Explained With Mobile Testing Examples

Gherkin is the structured plain-English language used in BDD testing.
Author:
Posted on:
May 16, 2026
Read time:
15 Minutes

Gherkin is a plain-text language for describing software behavior. It uses a small set of keywords (Feature, Scenario, Given, When, Then) to structure test scenarios in a way that anyone on team can read. Developers, QA engineers, and product managers all understand "Given user is logged in, When they tap Checkout, Then order confirmation appears."

Cucumber is tool that executes Gherkin. But Gherkin is just language. You can write Gherkin without Cucumber, and you can use Cucumber with languages other than Gherkin (though almost nobody does). The Gherkin file (.feature) describes behavior. The step definition file (Java, JavaScript, Python, Ruby) connects each Gherkin step to executable code.

This guide covers every Gherkin keyword with examples from mobile app testing, because that's where syntax is easy and execution gets hard.

The keywords

Feature

The top-level container. One .feature file describes one feature of app. The Feature line is a short title followed by an optional description.

Feature: Checkout with promo code
  As a returning customer
  I want to apply a promo code at checkout
  So that I get a discount on my order

The "As a / I want / So that" lines aren't Gherkin keywords. They're a convention borrowed from user stories. Cucumber ignores them. They're there for humans.

Scenario

One specific test case within feature. Each Scenario is independent. It should set up its own state, perform its action, and verify its result without depending on another Scenario.

Scenario: Valid promo code reduces total
  Given user has a $50 item in cart
  When user enters promo code "SAVE20"
  And taps "Apply"
  Then total should show "$40.00"
  And discount line should show "-$10.00"

Given

Sets up precondition. What's true before action happens. On mobile, this often includes device state: user is logged in, app is on home screen, GPS is set to a specific location, network is Wi-Fi.

Given user is logged in on Samsung Galaxy A14
And delivery address is set to "Koramangala, Bangalore"

When

The action user takes. One action per When step. If user does two things, use And.

When user taps "Express Checkout"
And enters card number "4242 4242 4242 4242"
And taps "Place Order"

Then

The expected result. What should be true after action. Be specific.

Then order confirmation screen appears within 3 seconds
And total shows "$40.00"
And order ID is visible

And / But

Continuations of previous keyword. And adds another condition. But adds a negative condition. Both are cosmetic. Cucumber treats them identically to whichever keyword they follow.

Given user is logged in
And has a $50 item in cart
But has no saved payment method

Background

Steps that run before every Scenario in feature file. Use it for shared setup instead of repeating same Given lines in every Scenario.

Feature: Checkout
Background:
  Given user is logged in
  And has a $50 item in cart
Scenario: Checkout with saved card
  When user taps "Express Checkout"
  Then order confirmation appears
Scenario: Checkout with new card
  When user taps "Pay with new card"
  And enters card details
  Then order confirmation appears

Without Background, both Scenarios would repeat same two Given lines. Background keeps file DRY.

Scenario Outline + Examples

Runs same Scenario multiple times with different data. This is Gherkin's version of data-driven testing.

Scenario Outline: Promo code validation
  Given the user has a $50 item in the cart
  When the user enters promo code "<code>"
  And taps "Apply"
  Then the message should show "<result>"

Examples:
  | code     | result                          |
  | SAVE20   | Discount applied: -$10.00       |
  | EXPIRED  | This promo code has expired     |
  | INVALID  | Invalid promo code              |
  | SAVE20   | Discount applied: -$10.00       |

Cucumber runs this Scenario four times, once per row in Examples table. It's cleanest way to cover multiple input/output combinations without duplicating Scenario.

A complete .feature file for a mobile login

Here's what a real .feature file looks like for a mobile login flow with multiple scenarios:

login.feature
Feature: Mobile loginBackground: Given app is installed on test device And user is on login screenScenario: Successful login with valid credentials When user types "user@test.com" in email field And types "Test@1234" in password field And taps "Log in" Then home screen loads within 3 seconds And header shows "Welcome, User"Scenario: Error message for invalid password When user types "user@test.com" in email field And types "wrongpassword" in password field And taps "Log in" Then error message "Invalid credentials" appears And email field still shows "user@test.com"Scenario Outline: Login with various invalid inputs When user types "" in email field And types "" in password field And taps "Log in" Then error message "" appearsExamples: | email | password | error | | notanemail | Test@1234 | Enter a valid email | | user@test.com | | Password is required | | | Test@1234 | Email is required |

That's readable by anyone on team. The product manager can review it and say "we also need a scenario for biometric login." The developer can confirm error messages match UI. The QA engineer can verify expected behavior matches spec.

For a full walkthrough of login test cases covering biometrics, SSO, and OTP, see our login testing guide.

The part most Gherkin guides skip: step definitions

The .feature file is easy part. The hard part is step definition file that makes each line executable. Here's what step definition looks like for "When user types 'user@test.com' in email field" on mobile using Appium:

step-definitions.js
When('user types {string} in email field', async (email) => { const emailField = await driver.$('~email-input'); await emailField.clearValue(); await emailField.setValue(email); });When('taps {string}', async (buttonText) => { const button = await driver.$(~${buttonText.toLowerCase().replace(/ /g, '-')}-button); await button.click(); });

Two things happen here that Gherkin file hides:

Selectors. '~email-input' is an accessibility ID. If developer renames it to '~login-email', step definition breaks. The Gherkin scenario ("types 'user@test.com' in email field") still reads perfectly. The code underneath it is broken. You don't know until test runs and fails.

Platform coupling. That step definition uses Appium's WebDriver protocol. It works on Android and iOS, but accessibility IDs might differ between platforms. The Gherkin scenario is platform-agnostic. The step definitions often aren't.

This is structural tension in Gherkin-based mobile testing. The scenarios are beautiful, stable, and readable. The step definitions are fragile, selector-dependent, and need maintenance every time UI changes. As we covered in our BDD testing guide, you're maintaining two layers instead of one.

For a deeper look at selector maintenance problem, see our test automation framework comparison.

When Gherkin works well

Gherkin is right choice in specific situations:

API testing. Gherkin scenarios for REST APIs don't depend on selectors. "Given I send a POST to /checkout with item_id 42, Then response status is 200 and total is $40." The step definition makes an HTTP call. No UI fragility. Gherkin + Cucumber is genuinely excellent for API-level BDD. See our API testing examples for reference.

When stakeholders read .feature files. If your product manager reviews Gherkin scenarios during sprint planning and catches missing edge cases before development starts, collaboration benefit is real. The Discovery phase of BDD (team discusses examples, writes them in Gherkin, agrees on behavior) is where most value comes from.

When your app has stable accessibility IDs. If your development team maintains consistent, well-named accessibility identifiers that don't change between builds, step definitions stay stable and maintenance burden is manageable.

When Gherkin adds overhead without payoff

When nobody reads .feature files. If scenarios are written by QA, maintained by QA, and never opened by product or development, Gherkin layer is overhead. You're maintaining readable English PLUS code underneath it, and readable English has an audience of one.

When UI changes every sprint. On mobile, every sprint brings layout changes, renamed elements, and new screens. Each change breaks step definitions. The Gherkin scenarios survive, but they're useless without working step definitions. You end up maintaining two things instead of one.

When your team is small. A 3-person team (1 dev, 1 QA, 1 PM) doesn't need formality of Gherkin. They can talk to each other. The communication problem Gherkin solves (shared understanding across a large team) doesn't exist at that scale.

Plain-English testing without step-definition layer

Drizz takes readability of Gherkin and removes step-definition layer. The plain English IS executable test:

drizz (plain english)
Tap on email field Type "user@test.com" Tap on password field Type "Test@1234" Tap "Log in" Validate "Welcome" is visible

No .feature file. No step definitions. No selectors. Vision AI reads screen and finds email field by what it looks like, not by an accessibility ID. The test runs on real devices across Samsung, Pixel, Xiaomi, and iPhone without platform-specific step definitions.

Ifra, QA Lead at NikahForever, described difference: "Drizz helped us simplify automation and maintain quality without usual grind. Broken tests and painful setups are not something we deal with anymore."

If your team gets value from Gherkin collaboration process (Discovery sessions, stakeholder reviews), keep using Gherkin for that. Then automate execution in Drizz instead of writing step definitions. You get shared understanding from Gherkin AND maintenance-free execution from Vision AI.

FAQ

What is Gherkin syntax?

It's a structured plain-English language for describing software behavior using keywords like Feature, Scenario, Given, When, Then, And, and But. It's used in BDD testing and executed by tools like Cucumber.

What's difference between Gherkin and Cucumber?

Gherkin is language (.feature files you write). Cucumber is tool that reads Gherkin files, matches each step to a step definition in code, and executes tests. Gherkin without Cucumber is documentation. Cucumber without Gherkin doesn't exist.

What is a Scenario Outline in Gherkin?

It's a way to run same scenario with different data inputs. You write scenario once with placeholder variables, then provide an Examples table with rows of test data. Cucumber runs scenario once per row.

Can Gherkin be used for mobile app testing?

Yes. The Gherkin scenarios themselves are platform-agnostic. The step definitions underneath need a mobile automation tool (Appium, Espresso, XCUITest) to interact with app. The challenge is maintaining those step definitions as mobile UI changes.

What language are step definitions written in?

Java, JavaScript, Python, Ruby, C#, or any language Cucumber supports. The step definition connects a Gherkin step ("When user taps Login") to executable code that actually taps Login button on device.

Is Gherkin same as BDD?

No. BDD is a development methodology (collaboration, shared understanding, behavior-first design). Gherkin is language used to write BDD scenarios. You can practice BDD without Gherkin, and you can write Gherkin without practicing BDD (though that misses point).

About the Author:

Schedule a demo