File snapshots or inline snapshots

edit

Two packages implement snapshot testing. They serialize values the same way, but store the expected value in different places:

  • Meziantou.Framework.SnapshotTesting (this section) stores it in a file next to the test.
  • Meziantou.Framework.InlineSnapshotTesting stores it in the source code of the test, as a string argument of the call, and rewrites that string when the snapshot is updated.
var user = new { Name = "John", Age = 42 };

// Meziantou.Framework.SnapshotTesting: the expected value is a file next to the test
Snapshot.Validate(user); // __snapshots__/SnapshotTests_DocumentationExample_FileAndInlineSnapshots.verified.txt

// Meziantou.Framework.InlineSnapshotTesting: the expected value is in the source code of the test
InlineSnapshot.Validate(user, """
    Name: John
    Age: 42
    """);

Differences

File snapshotsInline snapshots
AssertionSnapshot.Validate(value)InlineSnapshot.Validate(value, "expected")
Expected valueA .verified.* file in __snapshots__A string literal in the test
FormatsText, and any binary format: images, PDF documents, generated .cs files, ...Text only
Several files per assertionYes, such as the pages of a PDF documentNo
SerializationSeveral serializers chosen by the type of the value; extensions for images, PDF and RoslynOne serializer: human-readable, JSON or your own
ComparisonA comparer per format: text, bytes, pixels, ...One comparer for the text
Snapshot nameBuilt from the test; must be uniqueNone: the snapshot is where the call is
Failed assertionWrites an .actual fileShows the difference in the failure message
ApprovalApproval tool, update strategy or merge toolUpdate strategy or merge tool, which edit the source file
SettingsSnapshotSettingsInlineSnapshotSettings
Environment variablesSNAPSHOTTESTING_STRATEGY, SNAPSHOTTESTING_AUTODETECT_CONTINUOUS_ENVIRONMENTINLINESNAPSHOTTESTING_STRATEGY, INLINESNAPSHOTTESTING_AUTODETECT_CONTINUOUS_ENVIRONMENT

Both packages share the same update strategies (Disallow by default, Overwrite, OverwriteWithoutFailure, MergeTool, MergeToolSync), the same merge tool detection, the same line scrubbers, and never update snapshots on a build server, in a continuous testing runner or in an LLM agent.

Which one to choose

Choose inline snapshots when the serialized value is short: a few lines that you want to read next to the code that produces them, without opening another file. The test documents the expected result by itself, and a code review shows the code and its result together.

Choose file snapshots when:

  • the value is large, such as an API response, a generated file or a long report: a file keeps the test readable;
  • the value is binary or has a format of its own: an image, a PDF document, an SVG, JSON or C# you want to open with the right editor;
  • an assertion produces several files, such as the output of a source generator;
  • you want to review new snapshots before they are written, with the approval tool, rather than have the test run edit your source code.

You can use both packages in the same project, even in the same test.

Use both packages in the same file

Some types have the same name in both packages: SnapshotUpdateStrategy, MergeTool, Scrubber, and the scrub extension methods such as ScrubGuid. When a file imports both namespaces, these names are ambiguous. Import the namespace you use the most, and give the type you need from the other one an alias, such as using InlineSnapshot = Meziantou.Framework.InlineSnapshotTesting.InlineSnapshot;.