cucumber-gherkin

安装量: 82
排名: #9640

安装

npx skills add https://github.com/el-feo/ai-context --skill cucumber-gherkin

Cucumber & Gherkin Skill

BDD testing framework with plain-text executable specifications. Gherkin syntax with step definitions in Ruby, JavaScript, Java, or Python.

Core Concepts

Cucumber reads executable specifications in plain text and validates software behavior. Gherkin is the structured grammar making plain text machine-readable.

┌────────────┐ ┌──────────────┐ ┌───────────┐ │ Steps │ │ Step │ │ │ │ in Gherkin ├──matched with──>│ Definitions ├───manipulates──>│ System │ └────────────┘ └──────────────┘ └───────────┘

Gherkin Syntax Quick Reference Primary Keywords Feature: Short description Optional multi-line description explaining the feature.

Background: Given common setup steps for all scenarios

Rule: Business rule grouping (Gherkin 6+)

Scenario: Concrete example illustrating the rule
  Given an initial context (past tense, setup)
  When an action occurs (present tense, trigger)
  Then expected outcome (assertion)
  And additional step
  But negative assertion

Scenario Outline: Parameterized scenario
  Given there are <start> items
  When I remove <remove> items
  Then I should have <remaining> items

  Examples:
    | start | remove | remaining |
    |    12 |      5 |         7 |
    |    20 |      5 |        15 |

Step Keywords Keyword Purpose Example Given Setup/precondition Given I am logged in as "admin" When Action/trigger When I click the submit button Then Assertion/outcome Then I should see "Success" And Continue previous type And I have 3 items in my cart But Negative continuation But I should not see "Error" * Bullet-style step * I have eggs Data Structures

Data Tables - tabular data:

Given the following users exist: | name | email | role | | Alice | alice@example.com | admin | | Bob | bob@example.com | user |

Doc Strings - multi-line text:

Given a blog post with content: """markdown # My Post Title

This is the content of my blog post. """

Tags @smoke @critical Feature: User authentication

@wip Scenario: Login with valid credentials ...

@slow @database Scenario: Bulk user import ...

Tag expressions: @smoke and not @slow, @gui or @api, (@smoke or @critical) and not @wip

Step Definitions

Match Gherkin steps to code. Use Cucumber Expressions (preferred) or Regular Expressions.

Ruby Given('I have {int} cucumbers in my belly') do |count| @belly = Belly.new @belly.eat(count) end

When('I wait {int} hour(s)') do |hours| @belly.wait(hours) end

Then('my belly should growl') do expect(@belly.growling?).to be true end

With data table

Given('the following users exist:') do |table| table.hashes.each do |row| User.create!(row) end end

JavaScript const { Given, When, Then } = require('@cucumber/cucumber');

Given('I have {int} cucumbers in my belly', function(count) { this.belly = new Belly(); this.belly.eat(count); });

When('I wait {int} hour(s)', async function(hours) { await this.belly.wait(hours); });

Then('my belly should growl', function() { expect(this.belly.isGrowling()).toBe(true); });

// With data table Given('the following users exist:', async function(dataTable) { for (const row of dataTable.hashes()) { await User.create(row); } });

Java public class StepDefinitions { @Given("I have {int} cucumbers in my belly") public void iHaveCucumbersInMyBelly(int count) { belly = new Belly(); belly.eat(count); }

@When("I wait {int} hour(s)")
public void iWaitHours(int hours) {
    belly.wait(hours);
}

@Then("my belly should growl")
public void myBellyShouldGrowl() {
    assertTrue(belly.isGrowling());
}

}

Cucumber Expressions

Built-in parameter types: {int}, {float}, {word}, {string}, {} (anonymous)

Optional text: cucumber(s) matches "cucumber" or "cucumbers" Alternative text: color/colour matches "color" or "colour"

Hooks Scenario Hooks

Ruby

Before do |scenario| # runs before each scenario end

After do |scenario| # runs after each scenario screenshot if scenario.failed? end

// JavaScript const { Before, After } = require('@cucumber/cucumber');

Before(async function(scenario) { // runs before each scenario });

After(async function(scenario) { // runs after each scenario if (scenario.result.status === 'FAILED') { await this.screenshot(); } });

Conditional Hooks (with tags) Before('@database') do DatabaseCleaner.start end

After('@database') do DatabaseCleaner.clean end

Before({ tags: '@browser and not @headless' }, async function() { this.browser = await launchBrowser(); });

Global Hooks BeforeAll do # once before any scenario end

AfterAll do # once after all scenarios end

Best Practices Declarative over Imperative

Good (declarative):

When "Bob" logs in Then he sees his dashboard

Avoid (imperative):

When I visit "/login" And I enter "bob" in "username" And I enter "secret" in "password" And I click "Login" Then I should see "Dashboard"

Focus on Behavior, Not Implementation Describe what the system does, not how Use domain language stakeholders understand Keep scenarios short (3-5 steps recommended) One behavior per scenario Background Usage Keep backgrounds short (≤4 lines) Use only for essential shared context Move implementation details to step definitions Running Cucumber

Ruby

bundle exec cucumber cucumber --tags "@smoke and not @wip" cucumber features/login.feature:10 # specific line

JavaScript

npx cucumber-js npx cucumber-js --tags "@smoke"

Java (with Maven)

mvn test -Dcucumber.filter.tags="@smoke"

Additional References

For comprehensive details, see reference files:

references/gherkin-syntax.md - Complete Gherkin language reference references/step-definitions.md - Step definition patterns by language references/hooks-config.md - Hooks, configuration, and runners references/best-practices.md - Anti-patterns and advanced patterns

返回排行榜