Dream Test logo

Dream Test

Feature-rich unit and integration testing for Gleam.

Hex.pm Documentation License

Install Dream Test

gleam add --dev dream_test

Why Dream Test?

Rapid application development needs testing tools that scale and support the growing needs of the application without slowing down progress. Dream test was designed to help engineers write expressive unit and integration tests for their applications using the tools and techniques they know from other ecosystems; adapted properly to gleam and the beam.

Test Styles

FeatureWhat you get
πŸ§ͺ Unit testsdescribe/group/it for organizing tests
πŸ₯’ Gherkin specs.feature files or inline Gleam DSL
πŸ“Έ Snapshot testingLock in complex output without manual assertions

Assertions

FeatureWhat you get
⛓️ Pipe-first assertionsMatchers that chain and compose
πŸ“¦ Built-in matchersEquality, booleans, options, results, lists, strings, comparisons
🎁 Unwrapping matchersOption/Result matchers that unwrap for continued assertion
πŸ› οΈ Custom matchersWrite your own for your domain

Test Organization

FeatureWhat you get
πŸ”„ Lifecycle hooksbefore_all, after_all, before_each, after_each
πŸ”— Context-aware testsShared setup across tests with unit_context
🏷️ TagsFilter and organize test runs

Execution

FeatureWhat you get
⚑ Parallel executionConfigurable concurrency for fast runs
πŸ›‘οΈ IsolationCrashes and timeouts don’t break the run
⏱️ TimeoutsPer-test timeout control
πŸ” Test discoveryFind tests from file paths
🚨 Exit-on-failureFail fast for CI
🧩 Suite-specific execution configRun some suites sequential/with custom timeouts in the same runner (runner.add_suites_with_config(...))

Reporting

FeatureWhat you get
πŸ“ BDD results reporterHuman-readable, hierarchical output (printed at end)
πŸ“Š Progress reporterLive single-line progress bar during the run
πŸ“‹ JSON results reporterMachine-readable JSON (printed at end)
🌿 Gherkin formattingDedicated output for feature tests

Dream Test splits reporting into:

Full Usage Guide

  1. Installation
  2. Quick Start
  3. Writing Tests
  4. Context-Aware Tests
  5. Assertions & Matchers
  6. Lifecycle Hooks
  7. Runner & Execution
  8. Reporters
  9. Snapshot Testing
  10. Gherkin BDD
  11. Utilities

Unit Tests

import dream_test/matchers.{be_equal, or_fail_with, should}
import dream_test/reporters/bdd
import dream_test/reporters/progress
import dream_test/runner
import dream_test/unit.{describe, it}
import gleam/string

pub fn tests() {
  describe("String utilities", [
    it("trims whitespace", fn() {
      "  hello  "
      |> string.trim()
      |> should
      |> be_equal("hello")
      |> or_fail_with("Should remove surrounding whitespace")
    }),
  ])
}

pub fn main() {
  runner.new([tests()])
  |> runner.progress_reporter(progress.new())
  |> runner.results_reporters([bdd.new()])
  |> runner.exit_on_failure()
  |> runner.run()
}

πŸ§ͺ Tested source Β· πŸ“– Guide

Gherkin Integration Tests

Feature: Shopping Cart
  Scenario: Adding items
    Given I have 3 items in my cart
    When I add 2 more items
    Then I should have 5 items total
import dream_test/gherkin/feature.{FeatureConfig, to_test_suite}
import dream_test/gherkin/parser
import dream_test/gherkin/steps.{type StepContext, get_int, step}
import dream_test/gherkin/world.{get_or, put}
import dream_test/matchers.{be_equal, or_fail_with, should, succeed}
import gleam/result

fn step_have_items(context: StepContext) {
  put(context.world, "cart", get_int(context.captures, 0) |> result.unwrap(0))
  Ok(succeed())
}

fn step_add_items(context: StepContext) {
  let current = get_or(context.world, "cart", 0)
  put(context.world, "cart", current + { get_int(context.captures, 0) |> result.unwrap(0) })
  Ok(succeed())
}

fn step_verify_count(context: StepContext) {
  get_or(context.world, "cart", 0)
  |> should
  |> be_equal(get_int(context.captures, 0) |> result.unwrap(0))
  |> or_fail_with("Cart count mismatch")
}

pub fn tests() {
  let steps =
    steps.new()
    |> step("I have {int} items in my cart", step_have_items)
    |> step("I add {int} more items", step_add_items)
    |> step("I should have {int} items total", step_verify_count)

  let assert Ok(feature) = parser.parse_file("test/shopping_cart.feature")
  to_test_suite(FeatureConfig(feature: feature, step_registry: steps))
}

πŸ§ͺ Tested source Β· πŸ“– Guide

Gherkin Syntax in Gleam

import dream_test/gherkin/feature.{feature, given, scenario, then, when}
import dream_test/gherkin/steps.{type StepContext, get_int, step}
import dream_test/gherkin/world.{get_or, put}
import dream_test/matchers.{be_equal, or_fail_with, should, succeed}
import gleam/result

pub fn tests() {
  let steps =
    steps.new()
    |> step("I have {int} items", fn(ctx: StepContext) {
      put(ctx.world, "cart", get_int(ctx.captures, 0) |> result.unwrap(0))
      Ok(succeed())
    })
    |> step("I add {int} more", fn(ctx: StepContext) {
      let current = get_or(ctx.world, "cart", 0)
      put(ctx.world, "cart", current + { get_int(ctx.captures, 0) |> result.unwrap(0) })
      Ok(succeed())
    })
    |> step("I should have {int} items", fn(ctx: StepContext) {
      get_or(ctx.world, "cart", 0)
      |> should |> be_equal(get_int(ctx.captures, 0) |> result.unwrap(0))
      |> or_fail_with("Cart count mismatch")
    })

  feature("Shopping Cart", steps, [
    scenario("Adding items", [
      given("I have 3 items"),
      when("I add 2 more"),
      then("I should have 5 items"),
    ]),
  ])
}

πŸ§ͺ Tested source Β· πŸ“– Guide


Built in Gleam, on the BEAM, by the Dream Team.
✨ Search Document