Writing Feature Files
View SourceFeature files are the heart of Cucumber testing. They're written in Gherkin syntax, a business-readable domain-specific language that lets you describe application behavior without detailing how that behavior is implemented.
Feature File Structure
Feature files consist of several components:
Feature
Every feature file starts with the Feature: keyword followed by a name and optional description:
Feature: Shopping Cart
As a user
I want to add items to my cart
So that I can purchase them laterBackground
The Background: section contains steps that are executed before each scenario:
Background:
Given I am logged in as a customer
And the product catalog is availableScenarios
Scenarios are concrete examples of how the feature should behave:
Scenario: Adding an item to an empty cart
Given I am on the product page for "Ergonomic Keyboard"
When I click "Add to Cart"
Then I should see "Item added to cart" message
And my cart should contain 1 itemScenario Outlines
Scenario Outlines let you run the same scenario multiple times with different data. Use <placeholders> in step text and provide values in an Examples: table:
Scenario Outline: Adding items to cart
Given I have <count> items in my cart
When I add another <product>
Then I should have <total> items
Examples:
| count | product | total |
| 0 | Laptop | 1 |
| 2 | Headphones | 3 |Each row in the Examples table generates a separate test case.
Named Examples
Give Examples blocks descriptive names:
Scenario Outline: User authentication
Given I enter "<username>" and "<password>"
Then I should see "<result>"
Examples: valid credentials
| username | password | result |
| alice | secret | Welcome |
Examples: invalid credentials
| username | password | result |
| alice | wrong | Access denied|Tagged Examples
Apply tags to specific Examples blocks:
Scenario Outline: Payment processing
Given I pay with <method>
Then the payment should <status>
@smoke
Examples: common methods
| method | status |
| credit_card | succeed |
@slow @integration
Examples: alternative methods
| method | status |
| paypal | succeed |
| bitcoin | succeed |Tags on Examples blocks combine with tags on the Scenario Outline.
Placeholders in Step Arguments
Placeholders also work in doc strings and data tables:
Scenario Outline: Email templates
Given I send an email with body:
"""
Hello <name>,
Your order #<order_id> has shipped.
"""
Then the email should be sent
Examples:
| name | order_id |
| Alice | 12345 |Steps
Steps use keywords like Given, When, Then, And, and But:
Given: Establishes preconditionsWhen: Describes actionsThen: Specifies expected outcomesAnd/But: Continues the previous step type
Step Arguments
Gherkin supports several types of step arguments:
Data Tables
Scenario: Adding multiple items to cart
Given I have the following items in my cart:
| Product Name | Quantity | Price |
| Smartphone | 1 | 699.99|
| Protection Plan | 1 | 79.99 |
When I proceed to checkout
Then the total should be 779.98Doc Strings
Scenario: Submit feedback
When I submit the following feedback:
"""
I really like your product, but I think
it could be improved by adding more features.
Keep up the good work!
"""
Then my feedback should be recordedFile Organization
Feature files should be placed in a test/features/ directory and have a .feature extension. Organize them logically by feature or domain area:
test/
└── features/
├── authentication/
│ ├── login.feature
│ └── registration.feature
├── shopping/
│ ├── cart.feature
│ └── checkout.feature
└── user_profile.featureTags
Tags are used to categorize scenarios and can be used for filtering which tests to run:
@authentication @important
Feature: User Login
@happy_path
Scenario: Successful login with valid credentials
Given I am on the login page
When I enter valid credentials
Then I should be logged in
@error_handling
Scenario: Failed login with invalid credentials
Given I am on the login page
When I enter invalid credentials
Then I should see an error messageTags can be used at the Feature level (applies to all scenarios) or at the Scenario level.
Special Tags
@async
The @async tag enables concurrent test execution for features that don't share state:
@async
Feature: Independent Calculator Operations
This feature can run concurrently with other async tests
Scenario: Addition
Given I have a calculator
When I add 5 and 3
Then the result should be 8
Scenario: Multiplication
Given I have a calculator
When I multiply 4 and 7
Then the result should be 28Use @async only for features that:
- Don't share state with other tests
- Don't rely on test execution order
- Are truly independent of other tests
Note: Database tests can safely run async when using Ecto's SQL sandbox in shared mode. For non-Ecto resources (files, external APIs, etc.), ensure they can handle concurrent access.
Best Practices for Feature Files
- Keep language simple and consistent - Use clear, business-focused terminology
- One scenario per behavior - Each scenario should test one specific behavior
- Be specific in examples - Use concrete values rather than vague descriptions
- Use background wisely - Only for steps that are truly common to all scenarios
- Limit scenario length - If a scenario has many steps, consider breaking it down
- Organize with tags - Use tags to categorize and group related scenarios
- Think like a user - Write scenarios from the user's perspective
- Don't get too technical - Avoid technical implementation details in Gherkin