Skip to Content
Course content

209: Snapshot Testing with insta

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Why bother with snapshot testing when I can just use assert_eq!?

I've seen a lot of developers try to test complex data structures by writing a massive block of assert_eq! calls for every single field. It's tedious, and frankly, it's a nightmare to maintain. If you add one field to a struct, you have to update twenty different tests manually.

Snapshot testing solves this by saying: "I don't want to write the expected output by hand; I just want Rust to remember what the output looked like the last time it was correct." The first time you run the test, insta saves the output to a file (the snapshot). Every subsequent run compares the new output against that file. If they differ, the test fails. It's a lifesaver when you're dealing with large JSON blobs, YAML configs, or complex Debug prints.

How do I actually implement this in my code?

Let's say we're building a tool that generates a project manifest. Instead of asserting every string in the manifest, we can just snapshot the whole thing. First, add insta to your [dev-dependencies]. Then, you can use the assert_snapshot! macro.

#[derive(Debug, Serialize)]
struct ProjectManifest {
    name: String,
    version: String,
    dependencies: Vec<String>,
}

#[test]
fn test_manifest_generation() {
    let manifest = ProjectManifest {
        name: "my_cool_app".into(),
        version: "0.1.0".into(),
        dependencies: vec!["serde".into(), "tokio".into()],
    };

    // This will create a .snap file in your snapshots directory
    insta::assert_yaml_snapshot!(manifest);
}

I prefer assert_yaml_snapshot! or assert_json_snapshot! over the generic assert_snapshot! because they handle the serialization for you and make the resulting snapshot files much easier for humans to read in a git diff.

What happens when I actually change the output and the test fails?

This is where insta really beats the manual approach. When a test fails because the output changed, you don't go hunting through your source code to find the line that broke. Instead, you use the insta review tool.

Run this in your terminal:

cargo insta review

This opens an interactive CLI (or a web interface if you prefer) that shows you a side-by-side diff of the "old" snapshot and the "new" output. You can then decide: "Yes, this change was intentional, accept it," or "No, this is a regression, I need to fix my code." Once you accept, insta updates the snapshot file automatically. It turns a tedious chore into a quick decision process.

Can I use snapshots for things that aren't just data structs?

Absolutely. As long as the value implements Debug (or you can turn it into a string), you can snapshot it. I often use it for testing complex error messages or custom CLI output. If you're writing a compiler or a linter, snapshotting the error diagnostics is the only sane way to ensure you haven't accidentally changed the wording of your errors across a hundred different edge cases.

Just keep in mind: don't snapshot things that change every time they run, like timestamps or random IDs. If you do, your tests will fail every single time. You'll need to scrub that data (replace it with a placeholder like <TIMESTAMP>) before passing it to insta.




📋 Practical Task

Implementing Snapshot Tests for a Mock API Response

You are working on a client library that parses API responses from a weather service. The responses are deeply nested and complex, making assert_eq! impractical.

Your Task:

  • Create a WeatherResponse struct that includes fields for city, temperature, and a nested Forecast struct (containing a list of daily highs/lows).
  • Implement serde::Serialize for these structs.
  • Write a test called test_weather_serialization that uses insta::assert_json_snapshot! to verify the output of a sample WeatherResponse.
  • Once the snapshot is created, intentionally change one of the temperature values in your test data and run cargo test to observe the failure.
  • Use cargo insta review to inspect the diff and accept the change.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.