Library / SDK
VerifyTests/Verify avatar
VerifyTests/Verify

Verify: snapshot testing for complex .NET data models

Verify is a snapshot testing tool that simplifies the assertion of complex data models and documents.

3,468 stars189 forksC#MIT

At a glance

What is it?
VerifyTests/Verify serializes a test result to a file and compares it on the next run, turning large object graphs into reviewable snapshots. It targets .NET test suites, and from v33 it carries an Open Source Maintenance Fee for revenue-generating organizations.
Who is it for?
Adopt Verify if your .NET tests assert large object graphs, serialized documents or strings that are painful to write assertions for by hand, and you are willing to review snapshot diffs as part of code review. Do not adopt it if you need a license-free binary for a revenue-generating organization on a version released after 1 September 2026, or if your assertions are small enough that a plain equality check is clearer.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The assertion problem Verify was built for

Asserting a complex object graph by hand is tedious and brittle. A typical test ends up comparing a dozen properties, then a nested collection, then a formatted string, and every field you forget to check is a field that can silently regress. Verify takes a different route: instead of writing the expected value into the test, you let the library serialize the actual result and store it next to the test, named after the test.

The audience is .NET developers writing tests in NUnit, xUnit v3, MSTest, TUnit, Fixie or Expecto, where the assertion target is a model, a document or a serialized payload rather than a single scalar. The project describes itself as a snapshot tool that "simplifies the assertion of complex data models and documents", and that framing is accurate about the scope: it is not a general assertion library that replaces equality checks, it is a workflow for capturing and diffing serialized output.

How the snapshot compare cycle actually runs

The mechanism is a two-phase file comparison. Verify is called on the test result during the assertion phase. It serializes that result and stores it in a file whose name matches the test name. On the next execution, the result is serialized again and compared to the existing file. If the two snapshots differ, the test fails. The README states the failure has one of two meanings: the change was unexpected, or the reference snapshot needs to be updated to the new result.

That is the whole design, and it has consequences worth naming. The snapshot file becomes a committed artifact, so a diff in a pull request shows exactly what changed in the serialized output. It also means the serialization format matters: whatever the library writes is what reviewers read. Because the comparison is against a file on disk rather than an in-memory expectation, the first run of a new test produces no comparison at all, it produces the file that later runs will check against.

Accepting or declining a snapshot is described as part of the core workflow, and the README lists several ways to do it, including the Windows tray via DiffEngineTray and a ReSharper test runner plugin. The project treats the accept step as a matter of personal preference rather than prescribing one path.

Installing Verify and running a first snapshot test

Verify ships as framework-specific NuGet packages rather than one package. The README lists Verify.NUnit, Verify.XunitV3, Verify.Fixie, Verify.Expecto, Verify.MSTest and Verify.TUnit. Pick the one matching your runner. Requirements are stated as supported runtimes net462, net472, net48, net481, net6, net8, net9 and net10, and a supported SDK of 9.0.301 and up. The README points to a getting started wizard that generates instructions for your combination of operating system, IDE, test framework and build server, which is the right place to start because the setup differs per runner.

After restoring the package for your runner, a test calls Verify on the value you want to snapshot. The exact call shape depends on the framework package, and the wizard output is the authoritative source for it. The behaviour to expect on the first run is the key thing to understand: no snapshot file exists yet, so the test produces one rather than passing a comparison. On the second run, the serialized result is compared against that file.

If you are on a version released after 1 September 2026 and your organization generates revenue, the build also expects a sponsorship declaration. The README gives this snippet, placed once in a Directory.Build.props at the repository root:

xml
<PropertyGroup>
  <Verify_GitHubSponsorAccount>your-github-account</Verify_GitHubSponsorAccount>
</PropertyGroup>

According to the README, sponsorship is verified at build time by SponsorCheck, the check runs inside the build, adds no runtime dependency to the packages and issues no license keys.

The maintenance fee is the first thing to check

This is the part of the project that will decide adoption for a lot of teams, and it is easy to miss because the licence itself has not changed. The source code remains open and free under the MIT licence. What the Open Source Maintenance Fee covers is the use of the official binary releases and the packages published to NuGet, by organizations that generate revenue from them and by government agencies. Every version released after 1 September 2026 is covered; versions released on or before that date are not.

The fee is paid by sponsoring VerifyTests at a monthly tier based on organization size: $5 for fewer than 40 employees, $20 for 40 to 200, $30 for 200 to 1000, and $100 for more than 1000. The README points to a maintenance fee document for who the fee applies to, paying by invoice, and other declarations including exemptions, private arrangements and opting out.

Two operational details matter for upgrades. Each Verify version bundles the sponsor list as it stood when that version was packed, so a sponsorship that began later also needs a Verify_SponsorshipStart property in yyyy-MM-dd form until the next upgrade. A sponsorship made private on GitHub is never bundled, so it also needs Verify_SponsorshipPrivateUntil in yyyy-MM form, set at most 12 months out and renewed when it lapses. That means the declaration is not a one-time setup: it has to be revisited at each upgrade and whenever a private sponsorship lapses. This is a licence-adjacent arrangement, not a legal opinion, and teams with procurement rules should read the maintenance fee document rather than the README summary.

Where snapshots become the wrong tool

Snapshot testing moves the assertion out of the test body and into a file, and that trade is not always good. If your assertion is a single value, a boolean or a short string, a plain equality check states the intent directly and fails with a message a reader understands immediately. Verify adds a file, an accept step and a review obligation for no gain in that case.

The second failure mode is review fatigue. Because the snapshot captures whatever the serializer produces, a refactor that changes a property name or ordering can produce a large diff that reviewers approve without reading. The README's own framing is the warning here: the test fails either because the change was unexpected or because the reference snapshot needs updating, and nothing in the tool distinguishes those two situations for you. The accept step is a human judgement, and the tray and IDE plugin options exist precisely because that judgement happens often.

The third constraint is environmental. The supported runtime list is broad but finite, and the README states a minimum SDK of 9.0.301. Projects pinned to older SDKs or to runtimes outside net462, net472, net48, net481, net6, net8, net9 and net10 are outside what the README claims to support. The README does not document rollback behaviour for an accepted snapshot, so treat the snapshot files as source-controlled artifacts and rely on version control rather than on the tool.

Verify compared with hand-written assertions

The realistic alternative is not another snapshot library, it is writing the expected value into the test. That approach keeps everything in one place: the test file contains both the input and the expected output, and a failure message points at the exact property that differs. It scales badly as the object graph grows, which is the problem Verify exists to solve, but it stays readable for small assertions and it needs no accept workflow, no snapshot directory and no maintenance fee declaration.

The difference in approach is where the expected value lives. With hand-written assertions, the expected value is code you maintain alongside the test. With Verify, the expected value is a serialized file that the library produced and you approved. The second is faster to write and easier to keep current, and it is only as trustworthy as your review of the diffs. Teams that already review generated files carefully will find the workflow natural. Teams that treat generated output as noise will find that snapshots silently encode regressions.

Release cadence and what upgrades cost

The repository is not archived, and the last push was on 2026-09-23, the same day as the most recent releases listed: 33.1.1 on 2026-09-20, 33.1.0 on 2026-09-19 and 33.0.2 on 2026-09-14. Three releases in ten days is a fast cadence, and the README directs readers to closed milestones for release notes rather than maintaining a changelog in the readme itself.

Fast releases have a specific cost here because of the sponsorship bundling. Each version bundles the sponsor list as it stood when it was packed, so upgrading is not just a package version bump: if your sponsorship started after the version you were on, or if it is private on GitHub, the build properties described earlier have to be present before the upgrade builds cleanly. The README notes that the SponsorCheck setup wizard for Verify generates the exact snippet for the various declarations, which is the practical way to get the properties right rather than assembling them from the README by hand. The maintenance fee document is the source for who the fee applies to; the README is a summary.

Editorial conclusion

Adopt Verify if your .NET tests assert large object graphs, serialized documents or strings that are painful to write assertions for by hand, and you are willing to review snapshot diffs as part of code review. Do not adopt it if you need a license-free binary for a revenue-generating organization on a version released after 1 September 2026, or if your assertions are small enough that a plain equality check is clearer. Verify first which test framework package matches your runner (Verify.NUnit, Verify.XunitV3, Verify.MSTest, Verify.TUnit, Verify.Fixie or Verify.Expecto), and confirm your SDK is 9.0.301 or newer and your target runtime is one of net462, net472, net48, net481, net6, net8, net9 or net10.

Frequently asked questions

What is VerifyTests/Verify used for in a .NET test suite?

It is a snapshot tool for asserting complex data models and documents. It serializes the test result into a file named after the test, then compares the next run's serialized result against that file and fails if they differ.

Which NuGet package should I install for Verify?

There is no single package. The README lists Verify.NUnit, Verify.XunitV3, Verify.Fixie, Verify.Expecto, Verify.MSTest and Verify.TUnit, and you pick the one matching your test runner. The getting started wizard generates instructions for your operating system, IDE, test framework and build server.

What runtimes and SDK does Verify require?

The README states supported runtimes are net462, net472, net48, net481, net6, net8, net9 and net10, with a supported SDK of 9.0.301 and up.

Does Verify cost anything for commercial use?

The source code stays available under the MIT licence, but every version released after 1 September 2026 is covered by an Open Source Maintenance Fee for organizations that generate revenue and for government agencies. The fee is paid by sponsoring VerifyTests at a monthly tier based on organization size, from $5 for fewer than 40 employees to $100 for more than 1000.

How is the sponsorship declared in a Verify project?

A sponsoring organization declares its account once, in a Directory.Build.props at the repository root, using the Verify_GitHubSponsorAccount property. Because each Verify version bundles the sponsor list as it stood when packed, a later or private sponsorship also needs Verify_SponsorshipStart or Verify_SponsorshipPrivateUntil.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. VerifyTests/Verify on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/verifytests-verify.svg)](https://hysenlabs.com/projects/verifytests-verify)