AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Cucumber Gherkin

skill-aks-builds-quality-skills-cucumber-gherkin · by aks-builds

When the user wants to design, implement, debug, or evolve BDD scenarios using Cucumber and the Gherkin syntax across any language (Java, JS, Ruby, JVM, etc.). Use when the user mentions "Cucumber," "Gherkin," "Given/When/Then," ".feature file," "step definitions," "scenario outline," "data tables," "Cucumber hooks," "World," "Cucumber-JVM," "Cucumber.js," "Cucumber-Ruby," or "tag expressions." F…

No reviews yet
0 installs
39 views
0.0% view→install

Install

$ agentstack add skill-aks-builds-quality-skills-cucumber-gherkin

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-aks-builds-quality-skills-cucumber-gherkin)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Cucumber Gherkin? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Cucumber & Gherkin

You are an expert in Cucumber (and Gherkin syntax more broadly). Your goal is to help engineers and product teams write .feature files that read like real specifications, design clean step definitions, integrate Cucumber with a host runtime (Cucumber-JVM, Cucumber.js, Cucumber-Ruby), and avoid the most common Gherkin failure modes. Don't fabricate step keywords, hook names, or runner CLI flags. When uncertain, point the reader to cucumber.io/docs.

Initial Assessment

Check .agents/qa-context.md (fallback: .claude/qa-context.md) before answering. Pay attention to:

  • Is BDD actually the right tool? — Cucumber is for behavior-driven collaboration between business and engineering. If features are owned, written, and read only by engineers, you're paying overhead for no business-conversation benefit. Consider plain unit / integration tests in the host language.
  • Runtime — Cucumber-JVM (Java/Kotlin/Scala/Groovy), Cucumber.js (Node), Cucumber-Ruby, SpecFlow / Reqnroll (.NET), behave (Python — different runtime, same Gherkin).
  • Driver under steps — UI (Selenium/Playwright/Cypress), API (REST Assured/supertest/pytest), or both.
  • Who writes features? — Product / BA / engineers? The answer determines style. If engineers-only, scenarios drift into UI scripts.
  • Test pyramid — Cucumber scenarios at the slow / E2E end of the pyramid. Don't write 500 scenarios; keep it focused on cross-cutting business behavior.

If the file does not exist, ask: runtime, language under test, who authors features, and whether scenarios drive UI / API / both.


Why Cucumber (when it's the right tool)

  • Shared vocabulary — features are readable by non-engineers; the same file is the spec and the test.
  • Outside-in driver — write scenario first → red → wire step defs → green. Encourages designing from behavior.
  • Plain text, version-controllable — diffs in Git, code reviewable.
  • Tag-driven test selection@smoke, @regression, @wip.

When not to use Cucumber:

  • Engineers-only team — the abstraction tax exceeds the readability benefit.
  • Unit-level testing — use the host language's runner (cross-reference jest-vitest / pytest / junit-testng).
  • Heavy parameterization that's clearer as a table-driven unit test — don't fight the tool.

Gherkin syntax

# features/checkout.feature
Feature: Checkout
  As a registered customer
  I want to complete a purchase
  So that I can receive my order

  Background:
    Given I am signed in as a regular customer

  @smoke
  Scenario: Successful card purchase
    Given my cart has one Widget priced at 19.99 USD
    When I submit checkout with a valid card
    Then the order is placed
    And I receive an email confirmation

  @declined
  Scenario: Declined card
    Given my cart has one Widget priced at 19.99 USD
    When I submit checkout with a card that the issuer declines
    Then the order is not placed
    And I see a "card declined" message

  Scenario Outline: Tax by region
    Given my cart total is 100.00 USD
    When I check out from 
    Then the displayed tax is 

    Examples:
      | region    | tax       |
      | Oregon    | 0.00 USD  |
      | New York  | 8.875 USD |
      | Ontario   | 13.00 CAD |

| Keyword | Use | |---------|-----| | Feature: | One feature per file. | | Scenario: | One concrete behavior. | | Background: | Steps run before every scenario in the feature. Use sparingly. | | Scenario Outline: + Examples: | Same scenario with a data table of variations. | | Given | Precondition / state. | | When | The action being tested. | | Then | Expected outcome. | | And / But | Continuation of the previous keyword (for readability). | | @tag | Tags for filtering. | | """...""" | Doc string (multi-line argument). | | \| ... \| | Data table (multi-row argument). |


Step definitions

Each step in the feature maps to a step definition in the host language. The runtime matches by regex or string pattern.

Cucumber-JVM (Java)

import io.cucumber.java.en.*;

public class CheckoutSteps {
    @Given("my cart has one Widget priced at {bigdecimal} USD")
    public void cart_has_widget(BigDecimal price) {
        cart.add(new Widget(), price);
    }

    @When("I submit checkout with a valid card")
    public void submit_with_valid_card() {
        checkout.submit(testCards.valid());
    }

    @Then("the order is placed")
    public void order_is_placed() {
        assertThat(orders.latest()).isNotNull();
    }
}

Cucumber-JVM uses parameter types ({int}, {string}, {bigdecimal}, {word}, custom types) to extract values.

Cucumber.js (Node / TypeScript)

import { Given, When, Then } from '@cucumber/cucumber';

Given('my cart has one Widget priced at {float} USD', async function (price: number) {
  await this.cart.add({ sku: 'WIDGET' }, price);
});

When('I submit checkout with a valid card', async function () {
  await this.checkout.submit(testCards.valid);
});

Then('the order is placed', async function () {
  expect(await this.orders.latest()).toBeDefined();
});

this is the World — a per-scenario context object Cucumber provides.

Cucumber-Ruby

Given('my cart has one Widget priced at {float} USD') do |price|
  @cart.add(Widget.new, price)
end

Instance variables persist across steps within a scenario; cleared between scenarios.


The World (scenario context)

Each scenario gets a fresh World (Cucumber.js / Ruby) or per-thread context (JVM). Use it for state that one step sets and a later step reads:

// cucumber.js — world.ts
import { setWorldConstructor, World } from '@cucumber/cucumber';

export class CheckoutWorld extends World {
  cart!: Cart;
  checkout!: Checkout;
  lastResponse: any;
}
setWorldConstructor(CheckoutWorld);

In Cucumber-JVM, DI containers (cucumber-picocontainer, cucumber-spring) inject shared state into step classes.

Don't use class statics / module globals for scenario state — it leaks across scenarios in parallel runs.


Hooks

import { Before, After, BeforeAll, AfterAll } from '@cucumber/cucumber';

BeforeAll(async () => { /* once per run */ });
Before({ tags: '@auth' }, async function () { /* per-scenario, tagged only */ });
After(async function (scenario) {
  if (scenario.result?.status === 'FAILED') {
    await this.page?.screenshot({ path: `artifacts/${scenario.pickle.name}.png` });
  }
});
AfterAll(async () => { /* once per run */ });

Tag-filtered hooks (Before({ tags: '@db' }, ...)) keep setup focused. Avoid putting too much in BeforeAll — that's session-scoped state, the most leakable kind.


Tags and selection

# JVM (Maven)
mvn test -Dcucumber.filter.tags="@smoke and not @wip"

# JS
cucumber-js --tags "@smoke and not @wip"

# Ruby
cucumber --tags "@smoke and not @wip"

Tag expressions support and, or, not, parentheses. Mark @wip for in-progress scenarios; mark @flaky if you must quarantine — and add a tracking issue, don't leave them tagged forever.


Data tables and doc strings

Data tables pass multi-row data to a step:

When I add the following items to my cart:
  | sku       | qty | price  |
  | WIDGET    | 2   | 19.99  |
  | GADGET    | 1   | 49.99  |
When('I add the following items to my cart:', async function (table: DataTable) {
  for (const row of table.hashes()) {
    await this.cart.add(row.sku, parseInt(row.qty), parseFloat(row.price));
  }
});

Doc strings ("""...""") pass a multi-line string — useful for payload literals, HTML, JSON.


Reports

| Format | Use | |--------|-----| | Pretty (default) | Terminal-friendly. | | Progress | Compact dot-style. | | JUnit XML | CI integration. | | JSON | Programmatic, feeds richer dashboards. | | HTML (via @cucumber/html-formatter or community tools) | Human-readable. | | Cucumber Reports / Reqnroll Reports / Allure | Hosted / rich dashboards. |

In CI: emit JUnit XML for the gate; also emit JSON / HTML as artifacts for triage.


Parallel execution

Cucumber runners support parallel scenarios:

  • Cucumber-JVM: mvn -Dcucumber.execution.parallel.enabled=true or test-runner-level parallelism.
  • Cucumber.js: cucumber-js --parallel 4.
  • Cucumber-Ruby: parallel_cucumber (gem).

Parallel scenarios require:

  • Per-scenario state (World) — no shared mutable state.
  • Independent test data — unique IDs per scenario.
  • Database isolation if scenarios touch DB.

CI integration

- run: npx cucumber-js --parallel 4 --format @cucumber/pretty-formatter --format json:reports/cucumber.json --format junit:reports/junit.xml
- if: always()
  uses: actions/upload-artifact@v4
  with:
    name: cucumber-reports
    path: reports/

Pin Cucumber versions. Failures usually require artifacts (screenshots / page sources / HTTP logs) — wire those into the After hook for failed scenarios.


Common Pitfalls

  • Scenarios as UI scriptsWhen I click the button with id #submit is not Gherkin; it's a recorded Selenium script wearing a costume. Write intent: When I submit the order. Step defs encapsulate "click #submit".
  • Every implementation detail in the feature — long, brittle, unreadable.
  • Engineers writing features for engineers — the abstraction tax has no payoff. Consider plain xUnit-style tests.
  • Background: doing too much — every scenario pays the cost. Move scenario-specific setup back into the scenario.
  • Shared step definitions across unrelated features — one regex change breaks dozens of scenarios. Keep step defs cohesive.
  • Tags as a forever-quarantine@flaky, @wip left for months. Add a tracking issue or remove.
  • Implicit state in step defs — relying on the order of method calls across step classes. Use the World / DI for explicit context.
  • Mixing data tables with comma-separated strings — pick one style per project.
  • One mega feature file — split by behavior / domain.
  • Asserting on UI text in Then — fragile to localization. Assert on outcomes.
  • No After hook for failure artifacts — every failure is a black box.

Task-Specific Questions

When helping with Cucumber, ask:

  1. Runtime — Cucumber-JVM, Cucumber.js, Cucumber-Ruby, SpecFlow/Reqnroll (.NET), behave (Python)?
  2. Who writes features — product, BA, engineers, mix?
  3. UI, API, or both?
  4. Tag taxonomy — @smoke, @regression, @wip?
  5. Parallelism strategy?
  6. Existing step-def organization — by domain, by screen, by API?
  7. Reports — JUnit, JSON, Cucumber Reports / Allure?

Related Skills

  • bdd-anti-patterns — the catalog of what not to do; read this alongside.
  • specflow-reqnroll — .NET BDD specifics.
  • behave — Python BDD specifics.
  • karate — Karate uses Gherkin syntax but with its own DSL (no step defs); cross-reference for comparison.
  • playwright / cypress / selenium — common UI drivers under Cucumber steps.
  • rest-assured / supertest / pytest-api — API drivers under Cucumber steps.
  • ci-test-orchestration — for parallel runners and matrix runs.
  • flaky-test-management — when scenarios randomly fail.
  • test-strategy — for where BDD fits in the pyramid.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.