dream_test/gherkin/feature
Feature execution and TestSuite conversion for Gherkin tests.
This module converts parsed Gherkin features to dream_test TestSuites and provides an inline DSL for defining features directly in Gleam.
Two Approaches
- File-based: Parse
.featurefiles with standard Gherkin syntax - Inline DSL: Define features directly in Gleam code
Both approaches share the same step definitions and execution engine.
File-Based Usage
Parse a .feature file and convert to TestSuite:
import dream_test/gherkin/feature.{FeatureConfig, to_test_suite}
import dream_test/gherkin/parser
import dream_test/gherkin/steps.{new_registry, given, when_, then_}
import dream_test/runner
pub fn main() {
let steps = new_registry()
|> given("I have {int} items", have_items)
|> when_("I add {int} items", add_items)
|> then_("the total is ${float}", check_total)
let assert Ok(parsed) = parser.parse_file("features/cart.feature")
let config = FeatureConfig(feature: parsed, step_registry: steps)
to_test_suite("cart_test", config)
|> runner.run_suite()
}
Inline DSL Usage
Define features directly in Gleam without .feature files:
import dream_test/gherkin/feature.{
feature, scenario, given, when, then, and, with_tags,
}
pub fn tests() -> TestSuite {
let steps = cart_steps()
feature("Shopping Cart", steps, [
scenario("Adding items", [
given("I have an empty cart"),
when("I add 2 apples to the cart"),
then("the cart should contain 2 items"),
and("the total should be $3.00"),
])
|> with_tags(["happy-path"]),
])
}
Types
Configuration for running a feature.
Contains the parsed feature and step registry needed to execute it.
pub type FeatureConfig {
FeatureConfig(
feature: types.Feature,
step_registry: steps.StepRegistry,
)
}
Constructors
-
FeatureConfig( feature: types.Feature, step_registry: steps.StepRegistry, )Arguments
- feature
-
The parsed feature to run
- step_registry
-
Registry of step definitions
Configuration for an inline scenario.
Used with the inline DSL to define scenarios in Gleam code.
pub type InlineScenario {
InlineScenario(
name: String,
steps: List(InlineStep),
tags: List(String),
)
}
Constructors
-
InlineScenario( name: String, steps: List(InlineStep), tags: List(String), )Arguments
- name
-
Scenario name
- steps
-
List of step text (e.g., [“Given I have 5 items”, “When I add 3”])
- tags
-
Tags for filtering (e.g., [“happy-path”, “smoke”])
An inline step for the DSL.
pub type InlineStep {
InlineStep(keyword: String, text: String)
}
Constructors
-
InlineStep(keyword: String, text: String)Arguments
- keyword
-
Step keyword as string (“Given”, “When”, “Then”, “And”, “But”)
- text
-
Step text after the keyword
Values
pub fn and(text: String) -> InlineStep
Create an And step for inline DSL.
Example
and("I have a coupon")
pub fn background(
inline_steps: List(InlineStep),
) -> List(types.Step)
Define a background for inline features.
Background steps run before each scenario.
Example
let bg = background([
given("I am logged in"),
given("I have an empty cart"),
])
feature_with_background("Shopping", steps, bg, [...scenarios...])
pub fn but(text: String) -> InlineStep
Create a But step for inline DSL.
Example
but("I should not see errors")
pub fn feature(
name: String,
registry: steps.StepRegistry,
scenarios: List(InlineScenario),
) -> types.TestSuite
Define a feature inline in Gleam code.
Creates a TestSuite from inline scenario definitions without needing
a .feature file.
Parameters
name: Feature nameregistry: Step registry with step definitionsscenarios: List of inline scenarios
Returns
A TestSuite that can be run with runner.run_suite()
Example
feature("Shopping Cart", steps, [
pub fn feature_with_background(
name: String,
registry: steps.StepRegistry,
background_steps: List(types.Step),
scenarios: List(InlineScenario),
) -> types.TestSuite
Define a feature with a background.
Parameters
name: Feature nameregistry: Step registrybackground_steps: Steps to run before each scenarioscenarios: List of inline scenarios
pub fn given(text: String) -> InlineStep
Create a Given step for inline DSL.
Example
given("I have {int} items in my cart")
pub fn scenario(
name: String,
inline_steps: List(InlineStep),
) -> InlineScenario
Define an inline scenario.
Parameters
name: Scenario namesteps: List of inline steps
Example
scenario("Adding items", [
given("I have an empty cart"),
when_step("I add 5 items"),
then_step("I should have 5 items"),
])
pub fn then(text: String) -> InlineStep
Create a Then step for inline DSL.
Example
then("I should have {int} items")
pub fn to_test_cases(
module_name: String,
config: FeatureConfig,
) -> List(types.TestCase)
Convert a Feature to a flat list of TestCases.
Unlike to_test_suite, this flattens the feature to a simple list.
Use this when you don’t need before_all/after_all hooks.
Parameters
module_name: Name prefix for test pathsconfig: FeatureConfig with feature and step registry
Returns
A list of TestCases that can be run with runner.run_all()
pub fn to_test_suite(
module_name: String,
config: FeatureConfig,
) -> types.TestSuite
Convert a Feature to a TestSuite.
Creates a TestSuite with one test per scenario. Background steps are prepended to each scenario. ScenarioOutlines are expanded based on their examples table.
Parameters
module_name: Name for the suite (usually the test module name)config: FeatureConfig with feature and step registry
Returns
A TestSuite that can be run with runner.run_suite()
pub fn when(text: String) -> InlineStep
Create a When step for inline DSL.
Example
when("I add {int} items")
pub fn with_tags(
inline_scenario: InlineScenario,
tags: List(String),
) -> InlineScenario
Add tags to a Gherkin scenario for filtering.
Example
scenario("Adding items", [
when("I add 2 apples to the cart"),
then("the cart should contain 2 items"),
])
|> with_tags(["happy-path", "smoke"])
Note
This function is for Gherkin scenarios. For unit tests (it), use
dream_test/unit.with_tags instead.