InkSnap is a simple and lightweight snapshot testing library for Elixir
This package can be installed by adding :ink_snap to your list of dependencies
in mix.exs:
defdepsdo[{:ink_snap,git: "https://github.com/coherentpath/ink_snap",tag: "v*.*.*",only: [:dev,:test]}]endInkSnap is easy to use and is designed to integrate seamlessly with Elixir's
ExUnit module.
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.
defmoduleSampleTestdouseExUnit.CaseimportInkSnapsetup_alldo%{foo: 1,bar: 2}enddescribe"Map.put/3"do@tag:sample_tagtest_snapshot"will add a new pair to a map",ctxdoctx|>Map.put(:baz,3)|>Map.take([:foo,:bar,:baz])endendendOnce a snapshot test is defined, a snapshot file can be generated by running the
test with the SNAPSHOT_UPDATE flag set to true:
SNAPSHOT_UPDATE=true mix test test/sample_test.exs:12InkSnap 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.snap
Projects using InkSnap can also leverage the configured :snapshot_test_tag
to create a custom alias for generating snapshots:
defmoduleMyApp.MixProjectdouseMix.Projectdefprojectdo[aliases: ["snapshots.generate": &generate_snapshots/1],preferred_cli_env: ["snapshots.generate": :test],
...
]enddefpgenerate_snapshots(args)doSystem.put_env("SNAPSHOT_UPDATE","true")args=["--only","snapshot"]++argsMix.Tasks.Test.run(args)end...endOnce 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:12Renaming or removing a snapshot test (and regenerating with SNAPSHOT_UPDATE=true)
leaves the old snapshot file behind. Use the ink_snap.check task to detect these
stale/orphaned snapshots:
mix ink_snap.checkIt lists any snapshot file on disk that no test would produce and exits with a
non-zero status when orphans are found, making it suitable as a CI gate. To delete
the orphaned files (and prune any snapshot directories left empty), pass --delete:
mix ink_snap.check --deleteThe task compiles the project's test files to ask ExUnit for every registered
test, but it does not run any tests. It always runs in the test environment
(re-invoking itself if necessary), since that is where snapshots live.
InkSnap has a few few configuration options that can be set in the
application config:
# In config/test.exsconfig:ink_snap,snapshot_directory: "my_snapshot_dir",snapshot_test_tag: :my_test_tagMore specifically, the configuration options are:
:snapshot_directory- At:binary/0denoting the name of the snapshot directory. Defaults to_snapshots.:snapshot_test_tag- Ant:atom/0denoting the tag thatInkSnapuses to differentiate snapshot tests. Defaults to:snapshot.
InkSnap can also be used for projects with non-traditional test paths. For
more information on how to configure multiple test paths, see the mix testdocs.
In general, InkSnap 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.exsdefprojectdo[test_paths: ["test","other_test","other_test/dir"]]endInkSnap would only create two snapshot directories for the above project:
test/_snapshots
other_test/_snapshots
InkSnap 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.