cucumber-best-practices

安装量: 56
排名: #13141

安装

npx skills add https://github.com/thebushidocollective/han --skill 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 "" and "" Then I should see ""

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 "" Then result is ""

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

Keep Examples Meaningful Scenario Outline: Discount calculation Given a customer with "" status When they purchase items totaling $ Then they should receive a $ 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.

返回排行榜