When a Verify test fails, the exception message is designed to be machine-parsable. This enables tooling (IDE extensions, CI integrations, diff tools) to programmatically extract file paths and take action on verification failures.
The message has two parts: a file listing followed by optional file content.
The first line is always the directory:
Directory: /path/to/test/project
Then zero or more categorized sections, each listing file pairs:
- New - a
.received.file exists with no corresponding.verified.file (first test run or new test). - NotEqual - both files exist but content differs.
- Delete - a
.verified.file exists that is no longer produced by any test. - Equal - both files exist and match (included for completeness when other categories are present).
- InlineNew - an inline snapshot with no expected value yet.
- InlineNotEqual - an inline snapshot whose expected value differs from the result.
File paths in these sections are relative to the reported directory, and keep any subdirectory. UseUniqueDirectory and VerifyDirectory place snapshots in a subdirectory, so combining the reported directory with the listed path is what rebuilds the full path.
Inline entries use a different shape: a Source: line with the absolute source file path and 1 based line number (path:line), followed by optional absolute staged file paths:
InlineNotEqual:
- Source: /path/to/MyTests.cs:12
Received: /path/to/obj/VerifyInline/def.received.txt
Expected: /path/to/obj/VerifyInline/def.expected.txt
Patch: /path/to/obj/VerifyInline/def.inlinepatch
The staged path lines are omitted when staging was unavailable (build server, or the project does not consume Verify's build props). The Patch: file is readable via the DiffEngine InlinePatchFile API.
After the file listing, a FileContent: section includes the text content of new and not-equal files. This section is only present when there are text-based new or not-equal files. Binary files are listed in the file listing but their content is not included.
A not-equal text file shows a Diff: of the verified text against the received text, rather than both texts in full. Lines compare exactly, whitespace and case included. When the texts differ only in something a line diff does not see, such as line endings, both texts are shown in full instead.
The diff is produced by DiffEngine's TextDiff.Format, in one of three formats:
Compact(the default): the changed lines prefixed with-or+, each unchanged line next to a change prefixed with its received line number, and[BOF]or[EOF]where a change touches either end.Full: every line, prefixed with-,+or two spaces.Minimal: only the changed lines, prefixed with-or+.
Directory: {ProjectDirectory}
NotEqual:
- Received: VerifyExceptionMessageBuilderTests.Fake.received.txt
Verified: VerifyExceptionMessageBuilderTests.Fake.verified.txt
FileContent:
NotEqual:
Received: VerifyExceptionMessageBuilderTests.Fake.received.txt
Verified: VerifyExceptionMessageBuilderTests.Fake.verified.txt
Diff:
2 line 2
- line 3
+ line three
4 line 4
7 line 7
+ line 8
[EOF]The format is set globally:
public static class ModuleInitializer
{
[ModuleInitializer]
public static void Init() =>
VerifierSettings.UseTextDiffFormat(DiffEngine.TextDiffFormat.Full);
}To show both texts in full, as before diffs were shown, disable the diff:
public static class ModuleInitializer
{
[ModuleInitializer]
public static void Init() =>
VerifierSettings.DisableTextDiff();
}This only changes the exception message. Launching a diff tool is controlled separately, by DisableDiff.
Directory: {ProjectDirectory}
New:
- Received: MyTests.Test1.received.txt
Verified: MyTests.Test1.verified.txt
NotEqual:
- Received: MyTests.Test2.received.txt
Verified: MyTests.Test2.verified.txt
Delete:
- MyTests.OldTest.verified.txt
Equal:
- Received: MyTests.Test3.received.txt
Verified: MyTests.Test3.verified.txt
FileContent:
New:
Received: MyTests.Test1.received.txt
the new content
NotEqual:
Received: MyTests.Test2.received.txt
Verified: MyTests.Test2.verified.txt
Diff:
[BOF]
- verified text
+ received text
[EOF]Directory: {ProjectDirectory}
InlineNew:
- Source: {ProjectDirectory}MyTests.cs:10
Received: {ProjectDirectory}obj/VerifyInline/abc.received.txt
Expected: {ProjectDirectory}obj/VerifyInline/abc.expected.txt
Patch: {ProjectDirectory}obj/VerifyInline/abc.inlinepatch
FileContent:
InlineNew:
Source: {ProjectDirectory}MyTests.cs:10
Received:
the new contentDirectory: {ProjectDirectory}
InlineNotEqual:
- Source: {ProjectDirectory}MyTests.cs:12
Received: {ProjectDirectory}obj/VerifyInline/def.received.txt
Expected: {ProjectDirectory}obj/VerifyInline/def.expected.txt
Patch: {ProjectDirectory}obj/VerifyInline/def.inlinepatch
Delete:
- MyTests.OldTest.verified.txt
FileContent:
InlineNotEqual:
Source: {ProjectDirectory}MyTests.cs:12
Received:
received text
Expected:
expected textOnly the first target of a verification is inlined, so one message can carry an inline section and the file sections for the remaining targets together:
Directory: {ProjectDirectory}
InlineNotEqual:
- Source: {ProjectDirectory}MyTests.cs:14
NotEqual:
- Received: MyTests.Test1#01.received.txt
Verified: MyTests.Test1#01.verified.txt
Delete:
- MyTests.OldTest.verified.txt
FileContent:
InlineNotEqual:
Source: {ProjectDirectory}MyTests.cs:14
Received:
inline received
Expected:
inline expected
NotEqual:
Received: MyTests.Test1#01.received.txt
Verified: MyTests.Test1#01.verified.txt
Diff:
[BOF]
- verified text
+ received text
[EOF]When a custom comparer provides a message, the content section uses Compare Result: instead of a diff or the file content:
Directory: {ProjectDirectory}
NotEqual:
- Received: MyTests.Test1.received.txt
Verified: MyTests.Test1.verified.txt
FileContent:
NotEqual:
Received: MyTests.Test1.received.txt
Verified: MyTests.Test1.verified.txt
Compare Result:
The comparer reported a differenceThe FileContent: section can be suppressed globally:
public static class ModuleInitializer
{
[ModuleInitializer]
public static void Init() =>
VerifierSettings.OmitContentFromException();
}This is useful in CI environments where only the file paths are needed.
The Verify.ExceptionParsing NuGet package provides a parser for this format.
static Result ParseExceptionMessage(string exceptionMessage)
{
var result = Parser.Parse(exceptionMessage);
// result.New: files with no corresponding .verified. file
// result.NotEqual: files where .received. differs from .verified.
// result.Delete: .verified. files no longer produced by any test
// result.Equal: files where .received. matches .verified.
foreach (var file in result.NotEqual)
{
Debug.WriteLine($"Received: {file.Received}");
Debug.WriteLine($"Verified: {file.Verified}");
}
return result;
}The Result contains:
New- list ofFilePair(received and verified paths).NotEqual- list ofFilePair.Delete- list of file paths.Equal- list ofFilePair.InlineNew- list ofInlineEntry(source file, line, and optional staged paths).InlineNotEqual- list ofInlineEntry.
Different test frameworks prepend different prefixes to the exception message. The parser handles these automatically:
- NUnit:
VerifyException : Directory: ... - MSTest:
Test method ... threw exception:\nVerifyException: Directory: ... - Other frameworks:
Directory: ...