Skip to content
nulleanPublic

About

Lightweight snapshot testing for .NET on AwesomeAssertions

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

snapshots.

Structural snapshot tests for .NET: text, HTML, JSON, YAML, images, browser journeys and HTTP, compared by structure and reported in plain messages people and agents can act on.

NuGet CI Docs

An image snapshot's diff: the verified screenshot faded to grey, the changed heading in red, outlined in blue

A real diff image from Nullean.Snapshots.Images: the snapshots.nullean.net landing page, screenshotted, then again with one word of its heading changed. Everything else on the page matched.

Nullean.Snapshots is snapshot testing on AwesomeAssertions. A test's output is compared with a verified file kept with your tests, or with a string literal right in the test (inline snapshots); when it differs, the test fails with a short, plain message that says exactly what moved and how to accept it. A small native AOT CLI, snap, reviews and accepts what changed.

JSON did not match snapshot: tests/Shop.Tests/.snapshots/CatalogTests/Serializes.verified.json
3 difference(s):
$.items[0].name   expected "kibana"   actual "Kibana"   (verified.json:5:15)
$.items[1]        missing in actual   (verified.json:7:5)
$.extra           unexpected in actual
Received: .artifacts/.snapshots/received/Shop.Tests/CatalogTests/Serializes.received.json
Accept:   snap accept Shop.Tests/CatalogTests/Serializes   (or: dnx Nullean.Snapshots.Cli accept Shop.Tests/CatalogTests/Serializes)

Install

dotnet add package Nullean.Snapshots.AwesomeAssertions
dotnet add package Nullean.Snapshots.Json
dotnet add package Nullean.Snapshots.TUnit
dotnet tool install --global Nullean.Snapshots.Cli

Add the format packages you need (.Html, .Yaml, .Images.Assertions, .Browser.Assertions, .Http.Assertions); Nullean.Snapshots.TUnit gives every case of a data-driven TUnit test its own file. The packages need .NET 10.

Quick start

using AwesomeAssertions;
using Nullean.Snapshots;
using Nullean.Snapshots.Json;

public class CatalogTests
{
	[Test]
	public void Renders() =>
		Catalog.Render().Should().MatchSnapshot();          // .snapshots/CatalogTests/Renders.verified.txt

	[Test]
	public void Serializes() =>
		Catalog.ToJson().Should().MatchJsonSnapshot();      // compared as a tree, not as text

	[Test]
	public void Greets() =>
		Catalog.Greet("Kibana").Should().MatchInlineSnapshot("Hello, Kibana!");
}

The first run of a new snapshot fails and writes a received file. Read it, accept it, and commit the verified file:

snap            # walk through what changed: accept, reject or skip each snapshot
snap accept CatalogTests/Renders

From then on a change in output is a decision you make with the difference in front of you.

  • Compared by structure, not by text. HTML compares as a DOM; JSON and YAML compare as trees. Attribute order, whitespace, key order and 1 versus 1.0 do not fail a test, and a changed field is reported by its path, with the line and column in the verified file. Images compare by their pixels, perceptually and with anti-aliasing left out, so a screenshot passes on every machine.
  • Verified files, or the value right in the test. Short values can be inline snapshots: MatchInlineSnapshot("""…""") keeps the expected value as a string literal, and accepting rewrites that literal.
  • Messages people and agents can act on. Plain text without colour codes, repository-relative paths, at most 20 differences and 80 lines, and the exact command to accept. They read the same in a terminal, a CI log and an agent's context.
  • Two sites compared. snap journey compare and snap http compare run a journey or .http file against a baseline site and a preview and fail only on differences nobody expected, which are rules in a checked-in .differences file next to it; screenshots are compared too, with a diff image. See expected differences.
  • You accept, or nothing changes. Nothing is ever accepted for you. SNAPSHOT_ACCEPT=1 works on your machine; with CI set it is ignored, and the failure says so.
  • Tidy. Verified files live in one .snapshots/ folder per test project, mirroring your test files. Received files go to obj/ or your artifacts folder, never into source.
  • Lightweight. Every package is trimming- and native-AOT-safe, the core has no heavy dependencies, and every write goes through a file system scoped to the snapshot folders.

Packages

Package What it is
Nullean.Snapshots the core: the snapshot store, accept modes, scrubbers, the line and tree differs and the failure messages; the other packages build on it NuGet
Nullean.Snapshots.AwesomeAssertions Should().MatchSnapshot() and MatchInlineSnapshot() for text, and the base the format packages build on NuGet
Nullean.Snapshots.Html MatchHtmlSnapshot, MatchInlineHtmlSnapshot, BeHtml, ContainHtml, NotContainHtml; select, remove and transform first NuGet
Nullean.Snapshots.Json MatchJsonSnapshot and MatchInlineJsonSnapshot for JSON text and objects (AOT-safe through JsonTypeInfo<T>), BeJson NuGet
Nullean.Snapshots.PublicApi MatchApiSnapshot for an assembly's public API, stored as a .api file, with changes by path, who they break and the version bump NuGet
Nullean.Snapshots.Yaml MatchYamlSnapshot, MatchInlineYamlSnapshot, BeYaml; the YAML 1.2 core schema, anchors and merge keys, stored as written NuGet
Nullean.Snapshots.Images PNG screenshots compared by pixels, with a diff image on failure (ImageSnapshotFormat) NuGet
Nullean.Snapshots.Images.Assertions MatchImageSnapshot for AwesomeAssertions NuGet
Nullean.Snapshots.Browser browser journeys: agent-browser commands run in Chrome with Nullean.Cdp, each read compared as a tree (JourneySnapshot, snap journey run) NuGet
Nullean.Snapshots.Browser.Assertions MatchJourneySnapshot, MatchAriaSnapshot and JourneyTest for AwesomeAssertions NuGet
Nullean.Snapshots.Browser.Console runs a suite of journeys from the console with streamed results, grouped skips and readable failures, for snap journey run and any tool that wants the same output NuGet
Nullean.Snapshots.Http HTTP responses and .http files run with Nullean.HttpFileParser: status, chosen headers and JSON bodies compared as trees, secrets redacted (HttpSnapshot, HttpFileSnapshot, snap http run) NuGet
Nullean.Snapshots.Http.Assertions MatchHttpSnapshot, MatchHttpFileSnapshot and HttpFileTest for AwesomeAssertions NuGet
Nullean.HttpFileParser parses, lints and runs .http files on its own, with no dependency on the snapshot packages; the portable subset of the Visual Studio, REST Client and JetBrains dialects NuGet
Nullean.Snapshots.TUnit the running TUnit test's class, method and arguments, so every case gets its own file; [SnapshotFiles], [JourneyFiles] and [HttpFiles] data sources NuGet
Nullean.Snapshots.Cli snap: review, diff, accept, reject, and find orphaned snapshots; accepting an inline snapshot rewrites the literal in the test; snap journey run and snap http run check journeys and .http files without a test run NuGet

Versions are 0.x while the API settles.

Learn more

MIT licensed. Copyright Nullean and contributors.

About

Lightweight snapshot testing for .NET on AwesomeAssertions

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages