cucumber-best-practices

Cucumber Best Practices

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "cucumber-best-practices" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-cucumber-best-practices

Cucumber Best Practices

Master patterns and practices for effective Cucumber testing.

Scenario Design Principles

  1. Write Declarative Scenarios

Focus on what needs to happen, not how it happens.

❌ Imperative (implementation-focused):

Scenario: Add product to cart Given I navigate to "http://shop.com/products" When I find the element with CSS ".product[data-id='123']" And I click the button with class "add-to-cart" And I wait for the AJAX request to complete Then the element ".cart-count" should contain "1"

✅ Declarative (business-focused):

Scenario: Add product to cart Given I am browsing products When I add "Wireless Headphones" to my cart Then my cart should contain 1 item

  1. One Scenario, One Behavior

Each scenario should test exactly one business rule or behavior.

❌ Multiple behaviors in one scenario:

Scenario: User registration and login and profile update Given I register a new account When I log in And I update my profile And I change my password Then everything should work

✅ Separate scenarios:

Scenario: Register new account When I register with valid details Then I should receive a confirmation email

Scenario: Login with new account Given I have registered an account When I log in with my credentials Then I should see my dashboard

Scenario: Update profile Given I am logged in When I update my profile information Then my changes should be saved

  1. Keep Scenarios Independent

Each scenario should set up its own preconditions.

❌ Dependent scenarios:

Scenario: Create order When I create order #12345

Scenario: View order When I view order #12345 # Depends on previous scenario!

✅ Independent scenarios:

Scenario: View order Given an order exists with ID "12345" When I view the order details Then I should see the order information

  1. Use Background Wisely

Use Background for common setup, but don't overuse it.

✅ Good use of Background:

Feature: Shopping Cart

Background: Given I am logged in as a customer

Scenario: Add product to cart When I add a product to my cart Then my cart should contain 1 item

Scenario: Remove product from cart Given I have a product in my cart When I remove the product Then my cart should be empty

❌ Background doing too much:

Background: Given I am on the homepage And I click the menu And I navigate to products And I filter by category "Electronics" And I sort by price

Too much setup! Not all scenarios need all of this

Feature Organization

Group Related Scenarios

Feature: User Authentication

Scenario: Successful login ...

Scenario: Failed login with wrong password ...

Scenario: Account lockout after multiple failures ...

Use Tags Effectively

@smoke @critical Scenario: Login with valid credentials ...

@slow @integration Scenario: Password reset email workflow ...

@wip Scenario: OAuth login

Work in progress

...

Run specific tags:

Run smoke tests

cucumber --tags "@smoke"

Run all except WIP

cucumber --tags "not @wip"

Run smoke AND critical

cucumber --tags "@smoke and @critical"

Run smoke OR critical

cucumber --tags "@smoke or @critical"

Writing Good Gherkin

Use Domain Language

Write in the language of the business domain, not technical terms.

❌ Technical language:

Scenario: POST request to /api/users When I send a POST to "/api/users" with JSON payload And the response status is 201

✅ Domain language:

Scenario: Register new user When I register a new user account Then the user should be created successfully

Keep Steps at the Same Level

Don't mix high-level and low-level details.

❌ Mixed levels:

Scenario: Purchase product Given I am logged in When I add a product to cart And I click the element with ID "checkout-btn" # Too detailed! And I enter credit card "4111111111111111" # Too detailed! Then I complete the purchase

✅ Consistent level:

Scenario: Purchase product Given I am logged in And I have a product in my cart When I checkout with a credit card Then my order should be completed And I should receive a confirmation email

Avoid Conjunctive Steps

Don't use "And" to combine multiple distinct actions in prose.

❌ Conjunctive step:

When I log in and add a product to cart and checkout

✅ Separate steps:

When I log in And I add a product to my cart And I proceed to checkout

Scenario Outlines

Use for True Variations

Use Scenario Outlines when you need to test the same behavior with different data.

✅ Good use:

Scenario Outline: Login validation When I log in with "<username>" and "<password>" Then I should see "<message>"

Examples: | username | password | message | | valid | valid | Welcome | | invalid | valid | Invalid username | | valid | invalid | Invalid password | | empty | empty | Username required |

❌ Overusing Scenario Outline:

Don't use Scenario Outline for unrelated test cases

Scenario Outline: Multiple features When I use feature "<feature>" Then result is "<result>"

Examples: | feature | result | | login | success | | registration | success | | cart | empty | # These are different behaviors!

Keep Examples Meaningful

Scenario Outline: Discount calculation Given a customer with "<membership>" status When they purchase items totaling $<amount> Then they should receive a $<discount> discount

Examples: Standard discounts | membership | amount | discount | | silver | 100 | 5 | | gold | 100 | 10 | | platinum | 100 | 15 |

Examples: Minimum purchase thresholds | membership | amount | discount | | silver | 49 | 0 | | silver | 50 | 2.50 |

Step Definition Patterns

Create Reusable Steps

// Generic, reusable When('I fill in {string} with {string}', async function(field, value) { await this.page.fill([name="${field}"], value); });

// Used in multiple scenarios: When('I fill in "email" with "test@example.com"') When('I fill in "password" with "secure123"') When('I fill in "search" with "products"')

Avoid Over-Generic Steps

Balance reusability with readability.

❌ Too generic:

When('I do {string} with {string} and {string}', ...)

✅ Specific and readable:

When('I log in with {string} and {string}', ...) When('I search for {string} in {string}', ...)

Data Management

Use Factories for Test Data

// support/factories.js const faker = require('faker');

class UserFactory { static create(overrides = {}) { return { firstName: faker.name.firstName(), lastName: faker.name.lastName(), email: faker.internet.email(), password: 'Test123!', ...overrides }; } }

// Use in steps Given('I register a new user', async function() { const user = UserFactory.create(); this.currentUser = user; await this.api.register(user); });

Avoid Hardcoded IDs

❌ Hardcoded:

Given user "12345" exists When I view order "67890"

✅ Named entities:

Given a user "john@example.com" exists When I view my most recent order

Error Handling

Test Happy and Unhappy Paths

@happy-path Scenario: Successful checkout Given I have items in my cart When I complete the checkout process Then my order should be confirmed

@error-handling Scenario: Checkout with expired card Given I have items in my cart When I checkout with an expired credit card Then I should see an error message And my order should not be processed

@edge-case Scenario: Checkout with insufficient inventory Given I have a product in my cart But the product is out of stock When I attempt to checkout Then I should be notified about stock unavailability

Performance

Tag Slow Tests

@slow @integration Scenario: Full order workflow with email notifications

Takes 30 seconds to run

...

Parallel Execution

Ensure scenarios can run in parallel:

// cucumber.js module.exports = { default: '--parallel 4' };

Maintenance

Regular Review

  • Remove obsolete scenarios

  • Update scenarios when requirements change

  • Refactor duplicate steps

  • Keep features organized

Version Control

features/ authentication/ login.feature registration.feature shopping/ cart.feature checkout.feature admin/ user-management.feature

Common Anti-Patterns

❌ Testing implementation details:

Then the database should have 1 record in the users table

❌ UI-specific assertions in business scenarios:

Then I should see a red error message in the top right corner

❌ Using Given for actions:

Given I click the submit button # This is a When, not a Given!

❌ Technical jargon:

When I POST to /api/v1/users with JSON body

Testing Pyramid

Use Cucumber appropriately in your test strategy:

  • E2E Cucumber Tests: Critical user journeys (20%)

  • Integration Tests: API/service interactions (30%)

  • Unit Tests: Business logic (50%)

Don't try to test everything with Cucumber. Use it for high-value acceptance tests.

Remember: Cucumber tests should document behavior, facilitate collaboration, and provide confidence that the system works as expected from a business perspective.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

android-jetpack-compose

No summary provided by upstream source.

Repository SourceNeeds Review
General

fastapi-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

storybook-story-writing

No summary provided by upstream source.

Repository SourceNeeds Review
General

atomic-design-fundamentals

No summary provided by upstream source.

Repository SourceNeeds Review