- Less test code: Snapshot tests require less code to write.
- Reduced risk of incorrect test code: Given the above assertion based test it would be difficult to ensure that no property is missing from the assertion. For example if a new property is added to the model. In the snapshot test that change would automatically be highlighted when the test is next run.
- Test failure visualization: Snapshot test allows visualization in a diff tool that works for complex models and binary documents.
- Multiple changes visualized in singe test run: In the assertion approach, if multiple assertions require changing, this only becomes apparent over multiple test runs. In the snapshot approach, multiple changes can be visualized in one test run.
- Simpler creation of test "contract": In the assertion approach, complex models can require significant code to do the initial assertion. In the snapshot approach, the actual test and code-under-test can be used to create that "contract". See initial verification.
- Snapshot files committed to source control: All resulting snapshot files are committed to source control in the most appropriate format. This means these files can be viewed at any time using any tooling. The files can also be diff'd over the history of the code base. This works for any file type, for example:
- Html content can be committed as
.html
files. - Office documents can be committed as a rendered
.png
(see Verify.Aspose). - Database schema can be committed as
.sql
(see Verify.SqlServer).
- Html content can be committed as
Given the following method:
public static class ClassBeingTested
{
public static Person FindPerson() =>
new()
{
Id = new("ebced679-45d3-4653-8791-3d969c4a986c"),
Title = Title.Mr,
GivenNames = "John",
FamilyName = "Smith",
Spouse = "Jill",
Children =
[
"Sam",
"Mary"
],
Address = new()
{
Street = "4 Puddle Lane",
Country = "USA"
}
};
}
Compare a traditional assertion based test to a verification test.
[Fact]
public void TraditionalTest()
{
var person = ClassBeingTested.FindPerson();
Assert.Equal(new("ebced679-45d3-4653-8791-3d969c4a986c"), person.Id);
Assert.Equal(Title.Mr, person.Title);
Assert.Equal("John", person.GivenNames);
Assert.Equal("Smith", person.FamilyName);
Assert.Equal("Jill", person.Spouse);
Assert.Equal(2, person.Children.Count);
Assert.Equal("Sam", person.Children[0]);
Assert.Equal("Mary", person.Children[1]);
Assert.Equal("4 Puddle Lane", person.Address.Street);
Assert.Equal("USA", person.Address.Country);
}
[Fact]
public Task SnapshotTest()
{
var person = ClassBeingTested.FindPerson();
return Verify(person);
}
Produces a snapshot file SnapshotTest.verified.txt
:
{
GivenNames: John,
FamilyName: Smith,
Spouse: Jill,
Address: {
Street: 4 Puddle Lane,
Country: USA
},
Children: [
Sam,
Mary
],
Id: Guid_1
}
{
GivenNames: John,
FamilyName: Smith,
Spouse: Jill,
Address: {
Street: 4 Puddle Lane,
Country: USA
},
Children: [
Sam,
Mary
],
Id: Guid_1
}