# Snapshot
Snapshot is a library that makes testing code that has side-effects or is really slow for other reasons
as fast and relyable as your other tests, without writing a single line of code.
## Why would you want to use Snapshot:
* Slow tests (for instance testing a client that does a network requests), turn tests that take
seconds and make them run in microseconds.
* Reliable results (for instance testing a client that does
network requests but you don't want to break tests if the target website changes, or a network request times out)
* Having tests work in an environment that does not have access to the resources. For instance
you would like to test a client that reaches out to AWS S3 in a continuous integration environment
that does not have the AWS authentication keys setup in the test environment.
* Not have slow tests behind a `tag` (and always forget to run them), but run them everytime.
## How to add this
It's good practice to seperate out the client with side effects in a seperate module. Say we have
a HTTP client that looks like this:
defmodule Client
def get(url) do
...
end
end
To add Snapshot to this module and make tests of another Module that uses Client very fast we
only need to do this:
defmodule Client
use Snapshot
def get(url) do
...
end
end
Now our tests will create and use snapshots when the get function is used. Snapshot will do
this for all public (`def`) functions in the module. The default folder where snapshots are
saved is in `<your project>/test/snapshots` (but this can be configured by settting the `dir`
option in the configuration:
config :snapshot, dir: Path.join([__DIR__, "..", "test", "snapshots"])
If you'd like to remove the cached result just remove this folder (or specific files).
If you like to make sure the tests will always use the snapshots and never actually run the (network) code,
you can add the following afther the snapshots have been created. Now we get an error if a URL is requested
where we do not have a snapshot from yet.
defmodule Client
use Snapshot, locked: true
def get(url) do
...
end
end
The best thing about this? Due to the macro system, in production or development the snapshot
code is completely omitted. This means that adding snapshot has zero performance impact for
code that is not test-code.
## Installation
The package can be installed
by adding `snapshot` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:snapshot, "~> 0.1.0"}
]
end
```