View Source Exposure
Exposure is a simple and leightweight snapshot testing library for Elixir
Installation
This package can be installed by adding :exposure to your list of dependencies
in mix.exs:
def deps do
[
{:exposure, "~> 1.1.1", only: [:dev, :test]}
]
endDocumentation
For additional documentation, see HexDocs.
Usage
Exposure is easy to use and is designed to integrate seamlessly with Elixir's
ExUnit module.
Defining Snapshot Tests
Snapshot tests can be defined with the test_snapshot macro. This macro is
syntactically similar to the normal test macro and interacts with other
ExUnit entities in the same way.
defmodule SampleTest do
use ExUnit.Case
import Exposure
setup_all do
%{foo: 1, bar: 2}
end
describe "Map.put/3" do
@tag :sample_tag
test_snapshot "will add a new pair to a map", ctx do
ctx
|> Map.put(:baz, 3)
|> Map.take([:foo, :bar, :baz])
end
end
endUpdating Snapshot Files
Once a snapshot test is defined, a snapshot file can be generated by running the
test with the EXPOSURE_OVERRIDE flag set to true:
EXPOSURE_OVERRIDE=true mix test test/sample_test.exs:12
Exposure creates a snapshot directory for each test path and a snapshot file
for each test. The snapshot directory structure mirrors the test path directory
structure. For the example snapshot test above, the command would generate a
file at the following location:
test/_snapshots/sample_test/test_map_put_3_will_add_a_new_pair_to_a_map.snapProjects using Exposure can also leverage the configured :snapshot_test_tag
to create a custom alias for generating snapshots:
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
aliases: ["snapshots.generate": &generate_snapshots/1],
preferred_cli_env: ["snapshots.generate": :test],
...
]
end
defp generate_snapshots(args) do
System.put_env("EXPOSURE_OVERRIDE", "true")
args = ["--only", "snapshot"] ++ args
Mix.Tasks.Test.run(args)
end
...
endRunning Snapshot Tests
Once a snapshot file has been created, a snapshot test can be run in the same way as a normal test:
mix test test/sample_test.exs:12
Configuration
Exposure has a few few configuration options that can be set in the
application config:
# In config/test.exs
config :exposure,
snapshot_directory: "my_snapshot_dir",
snapshot_test_tag: :my_test_tagMore specifically, the configuration options are:
:snapshot_directory- Abinary/0denoting the name of the snapshot directory. Defaults to_snapshots.:snapshot_test_tag- Anatom/0denoting the tag thatExposureuses to differentiate snapshot tests. Defaults to:snapshot.Warning
The
:snapshot_test_tagconfiguration option must be available at compile time. If it's set inconfig/runtime.exs, it will not be respected.
Test Paths
Exposure can also be used for projects with non-traditional test paths. For
more information on how to configure multiple test paths, see the mix test
docs.
In general, Exposure creates a separate snapshot directory for each test path.
The only exception is if one test path contains another. In that case, a
snapshot directory is only created in the parent path. For example, consider a
project with the following configuration:
# In mix.exs
def project do
[
test_paths: ["test", "other_test", "other_test/dir"]
]
endExposure would only create two snapshot directories for the above project:
test/_snapshots
other_test/_snapshotsExposure requires that all snapshot tests exist within one of the project test
paths. In conjunction with the above simplification, this constraint guarantees
a consistent snapshot file location for every test.
Other Libraries
The Exposure API is heavily inspired by the
Snapshy library. For the vast
majority of cases, Snapshy is more than sufficient. The main differences are
relatively niche:
Exposurehas explicit support for additional test paths and umbrella apps.Exposurehas slightly different naming rules for snapshot files.Exposurerequires a snapshot to exist before running a test.
If those differences are unimportant for your project, Snapshy may be a better
choice.
Additionally, no discussion of snapshot testing in Elixir would be complete
without mentioning the
assert_value package.
The concept of a snapshot is handled slightly differently in assert_value but
the library is robust and mature and definitely worth investigating.