dream_test/discover
Test module discovery for Dream Test.
This module provides an ergonomic way to discover test modules at runtime
(compiled .beam modules) and load their tests/0 suites without having to
manually import every module.
Mental model
- You provide one or more module path globs (e.g.
"unit/**_test.gleam"). - Dream Test finds matching modules under
./test/that exporttests/0. - It calls
tests/0to getTestSuite(Nil)values.
Example
import dream_test/discover.{from_path, to_suites}
import dream_test/reporters/bdd
import dream_test/reporters/progress
import dream_test/runner.{exit_on_failure, progress_reporter, results_reporters, run}
pub fn main() {
let suites =
discover.new()
|> from_path("snippets/unit/**.gleam")
|> to_suites()
runner.new(suites)
|> progress_reporter(progress.new())
|> results_reporters([bdd.new()])
|> exit_on_failure()
|> run()
}
Note: discovery requires compiled BEAM modules.
Types
Result of loading suites, containing both successes and errors.
This is returned by load so callers can decide how to handle errors:
return them, log them, or convert them into failing suites via to_suites.
Fields
suites: successfully loaded suiteserrors: discovery or load errors (human-readable strings)
Example
let discover.LoadResult(suites: suites, errors: _errors) =
discover.tests("snippets/**.gleam")
|> discover.load()
pub type LoadResult {
LoadResult(suites: List(types.Root(Nil)), errors: List(String))
}
Constructors
-
LoadResult(suites: List(types.Root(Nil)), errors: List(String))
Builder for discovering test modules and loading their suites.
Discovery is built incrementally by adding one or more module-path glob
patterns (see from_path / tests).
TestDiscovery is opaque: you can only build/consume it through the
functions in this module.
Example
discover.tests("snippets/unit/**.gleam")
|> discover.load()
pub opaque type TestDiscovery
Values
pub fn from_path(
discovery discovery: TestDiscovery,
pattern pattern: String,
) -> TestDiscovery
Add a glob pattern to the discovery set.
You can call this multiple times to build up a list of globs.
Parameters
discovery: The current discovery builderpattern: A slash-separated module path glob (the.gleamextension is optional)
Returns
A new TestDiscovery with the pattern appended.
Example
import dream_test/discover.{from_path, to_suites}
import dream_test/reporters/bdd
import dream_test/reporters/progress
import dream_test/runner.{exit_on_failure, progress_reporter, results_reporters, run}
import gleam/io
pub fn main() {
let suites =
discover.new()
|> from_path("snippets/unit/**.gleam")
|> to_suites()
runner.new(suites)
|> progress_reporter(progress.new())
|> results_reporters([bdd.new()])
|> exit_on_failure()
|> run()
}
pub fn list_modules(
discovery discovery: TestDiscovery,
) -> Result(List(String), String)
List module names discovered for the configured pattern.
This returns the discovered module names (as strings) or an aggregated error message if discovery failed.
Parameters
discovery: The configured discovery builder
Returns
Ok(modules): A list of discovered module namesError(message): A human-readable error message (may contain multiple causes)
Example
import dream_test/discover
pub fn main() {
discover.tests("snippets/unit/**.gleam")
|> discover.list_modules()
}
pub fn load(discovery discovery: TestDiscovery) -> LoadResult
Load discovered suites and return both suites and errors.
This never panics; discovery errors are returned in LoadResult.errors.
Parameters
discovery: The configured discovery builder
Returns
A LoadResult with:
suites: successfully loadedTestSuite(Nil)valueserrors: discovery or load errors (as strings)
Example
import dream_test/discover
pub fn main() {
discover.tests("snippets/unit/**.gleam")
|> discover.load()
}
pub fn new() -> TestDiscovery
Create an empty discovery builder.
Most users will start with tests(pattern) instead.
Returns
A new empty TestDiscovery.
Example
import dream_test/discover.{from_path, to_suites}
import dream_test/reporters/bdd
import dream_test/reporters/progress
import dream_test/runner.{exit_on_failure, progress_reporter, results_reporters, run}
import gleam/io
pub fn main() {
let suites =
discover.new()
|> from_path("snippets/unit/**.gleam")
|> to_suites()
runner.new(suites)
|> progress_reporter(progress.new())
|> results_reporters([bdd.new()])
|> exit_on_failure()
|> run()
}
pub fn tests(pattern pattern: String) -> TestDiscovery
Start discovering tests matching a module path glob pattern.
The pattern is written using slash-separated module paths and may include
* / ** globs. The .gleam extension is optional.
Examples:
"unit/**_test.gleam""unit/errors/**_test.gleam""dream_test/**_test.gleam"
Parameters
pattern: A slash-separated module path glob (the.gleamextension is optional)
Returns
A new TestDiscovery initialized with the pattern.
Example
import dream_test/discover
import dream_test/reporters/bdd
import dream_test/reporters/progress
import dream_test/runner.{exit_on_failure, progress_reporter, results_reporters, run}
import gleam/io
pub fn main() {
let suites =
discover.tests("snippets/unit/**.gleam")
|> discover.to_suites()
runner.new(suites)
|> progress_reporter(progress.new())
|> results_reporters([bdd.new()])
|> exit_on_failure()
|> run()
}
pub fn to_suite(
discovery discovery: TestDiscovery,
suite_name suite_name: String,
) -> types.Root(Nil)
Build a single suite from discovered suites.
Any discovery/load errors are converted into failing unit tests tagged with
"discovery-error".
Parameters
discovery: The configured discovery buildersuite_name: Name to use for the outer group in the combined suite
Returns
A single TestSuite(Nil) containing:
- all discovered suites, and
- any errors as failing tests tagged
"discovery-error".
Example
import dream_test/discover
import dream_test/reporters/bdd
import dream_test/reporters/progress
import dream_test/runner.{exit_on_failure, progress_reporter, results_reporters, run}
import gleam/io
pub fn main() {
let suite =
discover.tests("snippets/unit/**.gleam")
|> discover.to_suite("discovered tests")
runner.new([suite])
|> progress_reporter(progress.new())
|> results_reporters([bdd.new()])
|> exit_on_failure()
|> run()
}
pub fn to_suites(
discovery discovery: TestDiscovery,
) -> List(types.Root(Nil))
Load discovered suites and return them as a list.
Any discovery/load errors are converted into failing unit tests tagged with
"discovery-error", so missing coverage is visible.
Parameters
discovery: The configured discovery builder
Returns
A list of suites. If any errors occurred, an additional failing suite tagged
"discovery-error" is appended.
Example
import dream_test/discover.{from_path, to_suites}
import dream_test/reporters/bdd
import dream_test/reporters/progress
import dream_test/runner.{exit_on_failure, progress_reporter, results_reporters, run}
import gleam/io
pub fn main() {
let suites =
discover.new()
|> from_path("snippets/unit/**.gleam")
|> to_suites()
runner.new(suites)
|> progress_reporter(progress.new())
|> results_reporters([bdd.new()])
|> exit_on_failure()
|> run()
}