Skip to content

Writing Features

Feature files are the heart of BDD. Written in Gherkin syntax, they describe system behavior in a human-readable format that serves as both documentation and executable tests.

Gherkin Basics

Gherkin is a domain-specific language designed to be understandable by everyone on the team—developers, testers, and business stakeholders alike.

Feature

Every feature file starts with the Feature keyword, followed by a name and optional description:

gherkin
Feature: Shopping Cart
  As a customer
  I want to add items to my cart
  So that I can purchase them later

The description (everything after the feature name) is free-form text. A common format is the "As a... I want... So that..." template, but any description works.

Scenarios

Scenarios are concrete examples of how the feature should behave:

gherkin
Feature: Shopping Cart

  Scenario: Add item to empty cart
    Given I have an empty cart
    When I add "Widget" to the cart
    Then I should see 1 item in my cart

  Scenario: Add multiple items
    Given I have an empty cart
    When I add "Widget" to the cart
    And I add "Gadget" to the cart
    Then I should see 2 items in my cart

Each scenario is independent and should not depend on other scenarios.

Steps

Steps are the building blocks of scenarios. They follow a specific structure:

KeywordPurposeTesting Phase
GivenSet up initial stateArrange
WhenPerform an actionAct
ThenVerify the outcomeAssert
AndContinue previous step type-
ButContinue with negation-
gherkin
Scenario: User login
  Given a user "john@example.com" exists        # Arrange
  And the user has password "secret"            # Arrange (continued)
  When I submit login with "john@example.com"   # Act
  And I enter password "secret"                 # Act (continued)
  Then I should be logged in                    # Assert
  But I should not see the login form           # Assert (continued)

Step Text Patterns

Plain Text Steps

Simple steps with no parameters:

gherkin
Given I am on the home page
When I click the login button
Then I should see the dashboard

Steps with Parameters

Parameters are enclosed in quotes for strings or written as bare numbers for integers:

gherkin
Given a user "John" exists              # String parameter
When I add 5 items to the cart          # Integer parameter
Then the total should be 99.99          # Float parameter

Multi-line Parameters

For longer text, use doc strings (triple quotes):

gherkin
Scenario: Post a comment
  Given I am logged in
  When I post a comment:
    """
    This is a multi-line comment.
    It can span several lines.
    Useful for longer text content.
    """
  Then I should see my comment

Tables

Use tables for structured data:

gherkin
Scenario: Bulk user creation
  Given the following users exist:
    | name  | email           | role  |
    | John  | john@test.com   | admin |
    | Jane  | jane@test.com   | user  |
    | Bob   | bob@test.com    | user  |
  Then I should see 3 users in the system

File Organization

Directory Structure

Place feature files in tests/Behaviors/:

tests/
├── Behaviors/
│   ├── authentication/
│   │   ├── login.feature
│   │   ├── logout.feature
│   │   └── password-reset.feature
│   ├── cart/
│   │   ├── add-items.feature
│   │   └── checkout.feature
│   └── user-management.feature
└── Steps/
    └── ...

Pest BDD automatically discovers all .feature files in this directory tree.

Naming Conventions

Feature files should:

  • Use lowercase with hyphens: user-registration.feature
  • Be descriptive: shopping-cart-checkout.feature
  • Group related scenarios in one file

One Feature Per File

Each file should contain exactly one feature:

gherkin
# Good: tests/Behaviors/user-registration.feature
Feature: User Registration
  ...

# Avoid: multiple features in one file

Comments

Add comments with the # character:

gherkin
Feature: User Authentication
  # This feature covers all authentication flows

  # Basic login scenario
  Scenario: Successful login
    Given a user exists
    # TODO: Add two-factor authentication step
    When I login with valid credentials
    Then I should be logged in

Tags

Tags categorize scenarios for filtering and organization:

gherkin
@authentication @smoke
Feature: Login

  @critical @fast
  Scenario: Valid credentials
    Given a user exists
    When I login with valid credentials
    Then I should be logged in

  @slow @integration
  Scenario: Remember me functionality
    Given a user exists
    When I login with "remember me" checked
    Then I should stay logged in for 30 days

Tags can be applied to:

  • Features (applies to all scenarios in the feature)
  • Scenarios (applies only to that scenario)

Learn more in Tag Filtering.

Best Practices

Write Declarative Steps

Good - Describes intent:

gherkin
Given a logged-in admin user
When I create a new product
Then the product should be visible

Avoid - Too implementation-specific:

gherkin
Given I open browser to "/login"
And I type "admin" in field "username"
And I type "password" in field "password"
And I click button "submit"

Keep Scenarios Focused

Each scenario should test one specific behavior:

Good:

gherkin
Scenario: Add item to cart
  Given I have an empty cart
  When I add "Widget" to the cart
  Then I should see 1 item in my cart

Avoid:

gherkin
Scenario: Complete shopping experience
  Given I am a registered user
  When I login
  And I browse products
  And I add item to cart
  And I checkout
  And I pay
  Then I should receive confirmation

Use Consistent Language

Create a ubiquitous language for your domain:

gherkin
# Consistent terminology
Given a customer "John" exists
When the customer adds "Widget" to cart
Then the customer's cart should contain "Widget"

# Avoid mixing terms
Given a user "John" exists           # user?
When the client adds "Widget"        # client?
Then the buyer's cart should...      # buyer?

Scenario Independence

Each scenario should be independent and not rely on others:

gherkin
# Good: Each scenario sets up its own state
Scenario: Add to empty cart
  Given I have an empty cart
  When I add "Widget"
  Then cart should have 1 item

Scenario: Add to existing cart
  Given I have a cart with "Gadget"
  When I add "Widget"
  Then cart should have 2 items

Example: Complete Feature File

Here's a well-structured feature file:

gherkin
@cart @e-commerce
Feature: Shopping Cart
  As a customer
  I want to manage items in my shopping cart
  So that I can purchase products I'm interested in

  Background:
    Given I am a logged-in customer

  @smoke @critical
  Scenario: Add item to empty cart
    Given I have an empty cart
    When I add "Wireless Mouse" to the cart
    Then I should see 1 item in my cart
    And the cart total should be $29.99

  @smoke
  Scenario: Add multiple items
    Given I have an empty cart
    When I add "Wireless Mouse" to the cart
    And I add "USB Cable" to the cart
    Then I should see 2 items in my cart

  Scenario: Remove item from cart
    Given I have a cart with "Wireless Mouse"
    When I remove "Wireless Mouse" from the cart
    Then I should have an empty cart

  Scenario: Update item quantity
    Given I have a cart with "Wireless Mouse"
    When I update the quantity of "Wireless Mouse" to 3
    Then I should see 3 "Wireless Mouse" in my cart
    And the cart total should be $89.97

  @slow
  Scenario: Cart persists across sessions
    Given I have a cart with "Wireless Mouse"
    When I logout and login again
    Then I should still see "Wireless Mouse" in my cart

Released under the MIT License.