Cucumber (Cucumber v1.0.0)

View Source

A behavior-driven development (BDD) testing framework for Elixir using Gherkin syntax.

Cucumber is a testing framework that allows you to write executable specifications in natural language. It bridges the gap between technical and non-technical stakeholders by allowing tests to be written in plain language while being executed as code.

Setup

Add to your test_helper.exs:

Cucumber.compile_features!()

File Structure

By default, Cucumber expects the following structure:

test/
  features/
    authentication.feature
    shopping.feature
    step_definitions/
      authentication_steps.exs
      shopping_steps.exs
      common_steps.exs
    support/
      hooks.exs

Configuration

You can customize paths in config/test.exs:

config :cucumber,
  features: ["test/features/**/*.feature"],
  steps: ["test/features/step_definitions/**/*.exs"]

Setting messages: "cucumber-messages.ndjson" additionally writes a Cucumber Messages NDJSON stream describing the run — see Cucumber.Messages.

Step Definitions

Create step definition modules using Cucumber.StepDefinition:

defmodule AuthenticationSteps do
  use Cucumber.StepDefinition

  step "I am logged in as {string}", %{args: [username]} = context do
    {:ok, Map.put(context, :current_user, username)}
  end
end

Running Tests

Cucumber tests run with mix test and can be filtered using tags:

# Run all tests including Cucumber
mix test

# Run only Cucumber tests
mix test --only cucumber

# Exclude Cucumber tests
mix test --exclude cucumber

Key Features

  • Auto-discovery of features and step definitions
  • Integration with ExUnit's tagging system
  • Context passing between steps
  • Support for data tables and doc strings
  • Rich error reporting with suggestions

Summary

Functions

Attaches data to the current step (or hook execution) for reporting.

Discovers and compiles all cucumber features into ExUnit tests.

Attaches a link to the current step.

Attaches a log message to the current step.

Functions

attach(context, data, media_type, opts \\ [])

@spec attach(map(), String.t() | {:bytes, binary()}, String.t(), keyword()) :: map()

Attaches data to the current step (or hook execution) for reporting.

Mirrors the attach API of reference Cucumber implementations: useful for capturing screenshots, response payloads, or logs while a scenario runs. Attachments are recorded against the step that attached them; until a step fails they are invisible, then they are listed in the failure output. (Cucumber Messages formatters will render them in reports, #28.)

data is either a string (attached as-is) or {:bytes, binary} for binary data, which is Base64-encoded — Elixir can't tell text from bytes by type, so binary data is marked explicitly.

Returns the context unchanged, so it composes with any step return style.

Options

  • :filename - a file name for the attachment (e.g. "screenshot.png")

Examples

step "I take a screenshot", context do
  Cucumber.attach(context, {:bytes, screenshot()}, "image/png",
    filename: "checkout.png"
  )
end

step "the API responds", context do
  context
  |> Cucumber.attach(response.body, "application/json")
  |> Map.put(:response, response)
end

compile_features!(opts \\ [])

@spec compile_features!(keyword()) :: [module()]

Discovers and compiles all cucumber features into ExUnit tests.

This function should be called in your test_helper.exs file.

Options

  • :features - List of patterns for feature files
  • :steps - List of patterns for step definition files
  • :support - List of patterns for support files

Examples

# Use default paths
Cucumber.compile_features!()

# Use custom paths
Cucumber.compile_features!(
  features: ["test/acceptance/**/*.feature"],
  steps: ["test/acceptance/steps/**/*.exs"]
)

link(context, uri)

@spec link(map(), String.t()) :: map()

Attaches a link to the current step.

Convenience for attach(context, uri, "text/uri-list") — the media type reference Cucumber implementations use for link. Returns the context unchanged.

log(context, text)

@spec log(map(), String.t()) :: map()

Attaches a log message to the current step.

Convenience for attach(context, text, "text/x.cucumber.log+plain") — the media type reference Cucumber implementations use for log. Returns the context unchanged.