Minitest::Snapshot - Snapshot testing
Coverage: 100%
Snapshot testing for Minitest - compare your test outputs against saved reference snapshots.
What is Snapshot Testing?
Snapshot testing is a way to verify that your code's output matches a previously saved "snapshot". Instead of manually writing expected outputs, you simply:
- Run the test once to generate the initial snapshot
- Verify the snapshot is correct
- In future test runs, your code's output will be compared against the saved snapshot
This is especially useful for testing complex objects, API responses, HTML, JSON, and other outputs that would be tedious to write assertions for.
This gem makes snapshot testing in Minitest similar to how it works in RSpec with rspec-snapshot.
Installation
Add this line to your application's Gemfile:
gem 'minitest-snapshot'
And then execute:
bundle install
Or install it yourself as:
gem install minitest-snapshot
Usage
Basic Usage
require 'minitest/autorun'
require 'minitest/snapshot'
class MyTest < Minitest::Test
def test_complex_object_matches_snapshot
complex_output = {
user: { name: 'Jane Doe', email: 'jane@example.com' },
permissions: ['read', 'write', 'admin']
}
assert_snapshot('user_with_permissions', complex_output)
end
def test_response_does_not_match_snapshot
unexpected_output = { status: 'error' }
refute_snapshot('successful_response', unexpected_output)
end
end
Using Expectation Syntax
require 'minitest/autorun'
require 'minitest/snapshot'
describe 'API Response' do
it 'matches the expected structure' do
response = {
data: {
id: 123,
attributes: { title: 'Example', content: 'Content' }
}
}
_(response).must_match_snapshot('api_response')
end
it 'has changed from the previous version' do
response = { version: 'v2', data: {...} }
_(response).wont_match_snapshot('api_response_v1')
end
end
Snapshot Naming
Snapshot names must follow these rules:
- Must not be empty
- Must not contain invalid filename characters (
< > : " | ? *
) - Must not include path traversal (
..
) - Must not include the file extension
Valid snapshot names:
'user_profile'
'api/responses/success'
Snapshot Files
By default, snapshots are stored in the __snapshots__
directory at the root of your project.
Snapshots in nested directories (e.g., 'api/responses/success'
) will be
stored in matching subdirectories.
Updating Snapshots
To update existing snapshots, run your tests with the UPDATE_SNAPSHOTS
environment variable:
UPDATE_SNAPSHOTS=1 bundle exec rake spec
Configuration
You can configure Minitest::Snapshot with custom options:
Minitest::Snapshot.configure do |config|
# Change the directory where snapshots are stored
config.snapshot_dir = 'test/fixtures/snapshots'
# Change the file extension for snapshot files
config.snapshot_file_extension = 'snap.json'
# Use a predefined serializer (:default, :json, or :yaml)
config.serializer = :json
# Configure JSON formatting options
config.json_options = { indent: ' ', object_nl: "\n" }
# Configure YAML formatting options
config.yaml_options = { line_width: 100 }
# Use a custom serializer
config.serializer = proc { |value| JSON.pretty_generate(value, indent: ' ') }
# Add a custom serializer for later use
config.add_serializer(:xml, proc { |value| value.to_xml })
# Then use it with:
# config.serializer = :xml
end
Available Serializers
-
:default
: UsesPP.pp
for pretty printing objects (good for Ruby objects) -
:json
: Formats output as JSON -
:yaml
: Formats output as YAML - Custom serializers can be added with
add_serializer
Example Workflow
- Write a test using
assert_snapshot
- Run the test for the first time - it will create the snapshot file
- Verify the snapshot file content is correct
- Run the test again - it will compare against the saved snapshot
- If you intentionally change the expected output, update the snapshot with
UPDATE_SNAPSHOTS=1
Development
After checking out the repo, run bin/setup
to install dependencies.
Then, run bundle exec rake spec
to run the tests.
You can also run bin/console
for an interactive prompt that will allow you to experiment.
Contributing
Bug reports and pull requests are welcome at github.com/kematzy/minitest-snapshot.
License
The gem is available as open source under the terms of the MIT License.
Credits
Code inspiration taken from rspec-snapshot by Mike Levin released under a MIT License.
This gem was essentially built because I wanted to experiment with Zed's AI coding assistant.
For that reason, most of the code documentation and a large portion of the tests were created by Claude Sonnet via Zed's Assistant UI.
Various other code parts were inspired by, or extracted from, Claude, Grok or ChatGPT answers.
- Zed's AI Assistant with Claude Sonnet 3.5 & 3.7
- xAI's Grok 3
- OpenAI's ChatGPT