white_bread alternatives and similar packages
Based on the "Testing" category.
Alternatively, view white_bread alternatives based on common mentions on social networks and blogs.
-
hound
Elixir library for writing integration tests and browser automation -
proper
PropEr: a QuickCheck-inspired property-based testing tool for Erlang -
bypass
Bypass provides a quick way to create a custom plug that can be put in place instead of an actual HTTP server to return prebaked responses to client requests. -
ExVCR
HTTP request/response recording library for elixir, inspired by VCR. -
StreamData
Data generation and property-based testing for Elixir. 🔮 -
excheck
Property-based testing library for Elixir (QuickCheck style). -
amrita
A polite, well mannered and thoroughly upstanding testing framework for Elixir -
power_assert
Power Assert in Elixir. Shows evaluation results each expression. -
FakerElixir
[unmaintained] FakerElixir generates fake data for you. -
shouldi
Elixir testing libraries with nested contexts, superior readability, and ease of use -
katt
KATT (Klarna API Testing Tool) is an HTTP-based API testing tool for Erlang. -
FakeServer
FakeServer integrates with ExUnit to make external APIs testing simpler -
Stubr
Stubr is a set of functions helping people to create stubs and spies in Elixir. -
mix_test_interactive
Interactive watch mode for Elixir's mix test. https://hexdocs.pm/mix_test_interactive/ -
mecks_unit
A simple Elixir package to elegantly mock module functions within (asynchronous) ExUnit tests using Erlang's :meck library -
test_selector
Elixir library to help selecting the right elements in your tests. -
factory_girl_elixir
Minimal implementation of Ruby's factory_girl in Elixir. -
toxiproxy_ex
ToxiproxyEx is an Elixir API client for the resilience testing tool Toxiproxy. -
mix_erlang_tasks
Common tasks for Erlang projects that use Mix -
ex_parameterized
This library support parameterized test with test_with_params macro. -
cobertura_cover
Output test coverage information in Cobertura-compatible format -
ex_unit_fixtures
A library for defining modular dependencies (fixtures) for ExUnit tests. -
ElixirMock
Creates clean, concurrent, inspectable mocks from elixir modules
Access the most powerful time series database as a service
Do you think we are missing an alternative of white_bread or a related project?
README
WhiteBread
Looking for maintainers
This project is looking for someone who'd like to take over ownershp: Discuss here: https://github.com/meadsteve/white-bread/issues/114
What?
Story BDD tool written in and for Elixir. Based on cucumber. Parses Gherkin formatted feature files and executes them as acceptance tests.
Is this a testing tool?
The short answer is no. The medium answer is it's a development tool that should really be used in conjuction with some testing framework. For a longer answer checkout this post by Aslak Hellesøy: the world's most misunderstood collaboration tool.
Why the name?
Gherkin and cucumber made me think of cucumber sandwiches. Which are traditionally made with very thin white bread.
Alternative tools
Before adopting whitebread you should investigate the alternaitves. This project (whitebread) contains a lot of code around setup, execution, and output of tests. An alternative gherkin based BDD tool can be found at https://github.com/cabbage-ex/cabbage. Cabbage parses gherkin feature files and creates exunit tests. This means a lot more of the logic is standard exunit code.
Getting started - installing
Add "white_bread" to your mix.exs
file with the version you wish to use:
defp deps do
[
...
{ :white_bread, "~> 4.1.1", only: [:dev, :test] }
...
]
end
Getting started - Basic usage
Create a features directory. In here add some *.feature files describing your software. They should be gherkin syntax like:
Feature: Serve coffee
Coffee should not be served until paid for
Coffee should not be served until the button has been pressed
If there is no coffee left then money should be refunded
Scenario: Buy last coffee
Given there are 1 coffees left in the machine
And I have deposited £1
When I press the coffee button
Then I should be served a coffee
Run the command:
mix white_bread.run
This should prompt you with a few messages like:
loading config from features/config.exs
Config file not found at features/config.exs.
Create one [Y/n]?
y
Suite: All
Context module not found Elixir.WhiteBreadContext (features/contexts/white_bread_context.exs)
Create one [Y/n]?
y
This will create a basic config file and also a context features/contexts/white_bread_context.exs
.
A context file tells WhiteBread how to understand the gherkin in your feature files and also
what setup is required.
These will need to be implemented like:
defmodule SunDoe.CoffeeShopContext do
use WhiteBread.Context
feature_starting_state fn ->
coffee_storage = setup_coffee_storage
%{in_memory_coffee_db: coffee_storage}
end
scenario_starting_state fn state ->
state.in_memory_coffee_db |> clear_db
state
end
# `_status` will be either {:ok, scenario} | {:error, reason, scenario}
scenario_finalize fn _status, state ->
state.in_memory_coffee_db |> shutdown_db
end
given_ "there are 1 coffees left in the machine", fn state ->
{:ok, state |> Dict.put(:coffees, 1)}
end
given_ ~r/^I have deposited £(?<pounds>[0-9]+)$/, fn state, %{pounds: pounds} ->
{:ok, state |> Dict.put(:pounds, pounds)}
end
when_ "I press the coffee button", fn state ->
# Domain logic to serve coffees would happen
# here. Then update the state with the result
{:ok, state |> Dict.put(:coffees_served, 1)}
end
then_ "I should be served a coffee", fn state ->
served_coffees = state |> Dict.get(:coffees_served)
# The context automatically imports ExUnit.Assertions
# so any usual assertions can be made
assert served_coffees == 1
{:ok, :whatever}
end
end
After doing this rerun
mix white_bread.run
If you want to run WhiteBread in test environment run this
MIX_ENV=test mix white_bread.run
To execute on each time WhiteBread in test environment without prefixing the command with MIX_ENV=test
, you can also add this line in mix.exs
def project do
[
...
preferred_cli_env: ["white_bread.run": :test],
...
]
end
Integrating a testing library
By default, use WhiteBread.Context
will import ExUnit.Assertions. If you're not using ExUnit, you'll probably want to override this default by calling use WhiteBread.Context, test_library: :some_other_library_name
.
At the moment, the only library names available are :ex_unit
(same as the default), :espec
, and nil
(which skips the test library setup step altogether).
Next steps - Additional Suites and subcontexts
After following the getting started steps you may find your default context starts to get a bit large. There are two ways this can be broken apart:
- By composing your default suite out of subcontexts using the
import_steps_from
macro. - By splitting your features into different suites each starting with a different context.
Subcontexts
Sub contexts allow the step definitions of multiple contexts to be imported in to a parent context. The parent context defines all the start and stop callbacks but all the steps in the child context will be available.
defmodule WhiteBread.Example.DefaultContext do
use WhiteBread.Context
import_steps_from WhiteBread.Example.SharedContext
# Rest of the context here as usual
#...
end
Multiple suites
Defining suites allows you to use a different starting context for groups of features. This will often be along the lines of a bounded context. You can also run one feature multiple times under different contexts. This is especially useful if you have a few different ways of accessing your software (web, rest api, command line etc.).
Suite configuration is loaded from features/config.exs
. An example with multiple suites is:
defmodule WhiteBread.Example.Config do
use WhiteBread.SuiteConfiguration
suite name: "Default",
context: WhiteBread.Example.DefaultContext,
feature_paths: ["features/sub_dir_one"]
suite name: "Alternate",
context: WhiteBread.Example.AlternateContext,
feature_paths: ["features/sub_dir_two"]
suite name: "Alternate - Songs",
context: WhiteBread.Example.AlternateContext,
feature_paths: ["features/sub_dir_one"],
tags: ["songs"]
end
Each suite gets run loading all the features in the given paths and running them using the specified context. Additionally the scenarios can be filtered to specific tags.
Suites: Context per feature
This is part of the Suite Configuration and it automatically maps a .feature
with a context
module file automatically.
It is also possible to run this with additional manually defined suites.
Example:
defmodule WhiteBread.Example.Config do
use WhiteBread.SuiteConfiguration
context_per_feature namespace_prefix: WhiteBread.Example,
entry_path: "features/context_per_feature"
# Extra config can also be provided to apply to each generated suite
context_per_feature namespace_prefix: WhiteBread.Example,
entry_path: "features/context_per_feature",
extra: [
tags: ['special']
]
suite name: "Alternate",
context: WhiteBread.Example.AlternateContext,
feature_paths: ["features/sub_dir_two"]
end
About the context_per_feature
configuration:
namespace_prefix:
the namespace your modules will start with. The file name of the feature will be converted into a module name and appended to the end of thenamespace_prefix
e.g.my_new_sandwich.feature
toWhiteBread.Example.MyNewSandwichContext
entry_path:
the location of your feature files.
note: context files need to be added to your features/contexts
folder still.
Speeding things up - async running
More than likely you have a multicore machine. To get things going a little faster each suite can be configured to run all features and scenarios in a separate process.
This can be done by setting run_async to true on any suite:
defmodule WhiteBread.Example.Config do
use WhiteBread.SuiteConfiguration
suite name: "Speedy run",
context: WhiteBread.Example.DefaultContext,
feature_paths: ["features/sub_dir_one"],
run_async: true
end
note: At the moment each suite will be run sequentially in the order they appear in the config file.
Speeding things up - timeouts
By default each scenario gets 30 seconds to execute. After which point it will fail with a timeout warning. Each context can define a custom timeout function:
defmodule WhiteBread.Example.DefaultContext do
use WhiteBread.Context
scenario_timeouts fn _feature, scenario ->
case scenario.name do
"possible slow scenario" -> 60_000
_ -> 5000
end
end
# Rest of the context here as usual
#...
end
This function gets the full structs representing the feature and scenario being executed so it's possible to base the decision to change the timeout on any available property: tags, name, description etc.
HTML Output (and other outputs)
For HTML reports configure WhiteBread (e.g. in config.exs
) with the HTML outputer and optionally a file name for the document:
JSON reports are also available.
config :white_bread,
outputers: [{WhiteBread.Outputers.Console, []},
{WhiteBread.Outputers.HTML, path: "~/build/whitebread_report.html"},
{WhiteBread.Outputers.JSON, path: "~/build/whitebread_report.json"}
]
Public interface and BC breaks
The public interface of this library covers:
- The exported mix command:
mix white_bread.run
- The
WhiteBread
andWhiteBread.Helpers
modules. - The macros exported by the
WhiteBread.Context
module. - The ContextBehaviour defined in
WhiteBread.ContextBehaviour
. - The config.exs structure and the macros exported by the
WhiteBread.SuiteConfiguration
module. - The structures defined in
WhiteBread.Gherkin
. - The location of feature and context files loaded automatically.
- The messages that custom outputers receive (documented in WhiteBread.Outputer)
Any changes outside of the above will not be considered a BC break. Although every effort will be made to not introduce unnecessary change in any other area.
Contribute
Contributions more than welcome but please raise an issue first to discuss any large changes.