
На рынке существует много хороших инструментов для снапшот-тестирования в .NET. Однако особенно выделяются два — Verify и Storm Petrel. Оба предлагают уникальные подходы к работе с ожидаемыми значениями (baseline) в модульных и интеграционных тестах, но заметно отличаются по методике и реализации.
Verify ориентирован на файловую работу со снапшотами: он сериализует ожидаемые данные, сохраняет их в виде файлов и использует специальные расширения и инструменты для сравнения.
Storm Petrel, напротив, применяет кодоцентричный подход — с помощью пошаговой генерации кода он обновляет ожидаемые данные прямо в C#-тестах.
Понимание этих различий поможет выбрать подходящий инструмент в зависимости от потребностей проекта.
Что такое Verify .NET?
Verify .NET — это набор NuGet-пакетов, инструментов управления снапшотами и расширений, упрощающих снапшот-тестирование в .NET.
Он предоставляет расширения для сериализации, сравнения и проверки ожидаемых значений в популярных библиотеках и фреймворках .NET. Verify помогает организовать снапшот-тестирование, сравнивая и переписывая baseline, хранящиеся в файловой системе.
Что такое Storm Petrel .NET?
Storm Petrel .NET — это инструмент, основанный на механизме пошаговой генерации кода (incremental code generation), который обновляет ожидаемые значения непосредственно в C#-тестах, минуя файлы со снапшотами. Он поддерживает модульные и интеграционные тесты в самых популярных .NET-фреймворках.
Работа с файловыми снапшотами в Storm Petrel рассматривается как частный случай управления ожидаемыми значениями. Для этого предусмотрен отдельный пакет — FileSnapshotInfrastructure, реализующий часть абстракции Storm Petrel.
Техническое сравнение: Verify vs. Storm Petrel
Ниже мы сравнили Verify и Storm Petrel по основным параметрам: как каждый из них работает со снапшотами, обновляет тесты и какие тестовые фреймворки поддерживает.
Требования к рефакторингу тестов
При использовании Verify разработчикам приходится преобразовывать классические тесты с утверждениями в снапшот-тесты.
[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);
}
С использованием FluentAssertions:
[Fact]
public void TraditionalTestViaAssertionLibrary()
{
var person = ClassBeingTested.FindPerson();
person.Should().BeEquivalentTo(new Person
{
Id = new("ebced679-45d3-4653-8791-3d969c4a986c"),
Title = Title.Mr,
GivenNames = "John",
FamilyName = "Smith",
Spouse = "Jill",
Children = new List<string>
{
"Sam",
"Mary"
},
Address = new Address
{
Country = "USA",
Street = "4 Puddle Lane",
}
});
}
[Fact]
public Task SnapshotTest()
{
var person = ClassBeingTested.FindPerson();
return Verify(person);
}
В Verify объект person сериализуется и сохраняется в файл — для процесса первичной и последующей проверки.
Storm Petrel не требует переработки традиционных тестов. Как описано в разделе “Snapshot Testing with Scand.StormPetrel.Generator without Serialization”, инструмент сохраняет все ключевые преимущества традиционного подхода к тестированию.
Для работы с файловыми снапшотами в Storm Petrel достаточно вызвать методы, например:
`Scand.StormPetrel.FileSnapshotInfrastructure.SnapshotProvider.ReadAllText()`
или
`SnapshotProvider.ReadAllBytes()`
в зависимости от вариантов использования.
Хранение и управление снапшотами
Verify поддерживает плагины для тест-раннеров ReSharper и Rider, тогда как Storm Petrel в этом не нуждается. Последний использует встроенную инфраструктуру .NET и среды разработки для запуска автогенерируемых тестов и обновления ожидаемых данных. После обновления разработчики могут использовать любые сторонние инструменты для сравнения изменений.
Verify предлагает широкий набор расширений (например, Verify.AspNetCore, Verify.WinForms, Verify.Xaml), адаптированных под популярные библиотеки. В Storm Petrel подобные расширения не требуются: ожидаемые значения либо представлены прямо в виде C#-кода, либо сериализуются в файлы с помощью сторонних решений.
Поддерживаемые тестовые фреймворки
Verify работает примерно с шестью тестовыми фреймворками, включая xUnit, NUnit, MSTest и даже F#. Storm Petrel на данный момент поддерживает только три самых популярных — xUnit, NUnit и MSTest.
Механизмы сравнения и обновлений
Verify включает встроенный движок для сравнения и поддерживает интеграцию с различными инструментами. Storm Petrel обновляет ожидаемые значения напрямую в коде и предоставляет полную свободу в выборе diff-утилит для последующего сравнения изменений.
Плюсы и минусы Verify и Storm Petrel
Ниже приведены ключевые преимущества и недостатки каждого подхода (хотя этот список не является полным).
Плюсы Verify:
- Интерактивность: позволяет сравнивать и управлять фактическими и ожидаемыми снапшотами прямо в процессе выполнения тестов.
- Специализированные расширения: поддержка популярных .NET-библиотек с готовой сериализацией.
- Широкая поддержка: поддержка большего количества фреймворков.
Минусы Verify:
- Нет поддержки baseline в C#-коде: нельзя сохранять ожидаемые значения прямо в коде.
- Требует рефакторинга: традиционные тесты требуют переработки.
- Сложность: требует времени на освоение, особенно при работе с кастомными типами объектов.
Плюсы Storm Petrel:
- Традиционный подход: позволяет использовать привычные тесты без необходимости их переписывать.
- Гибкость: поддерживает как хранение ожидаемых значений прямо в коде, так и работу с файловыми снапшотами.
- Простота: не требует специальных расширений или сложной конфигурации.
Минусы Storm Petrel:
- Отсутствие встроенной интерактивности: для сравнения изменений нужно использовать сторонние diff-инструменты.
- Ограниченная совместимость: отсутствует поддержка F# и менее распространенных тестовых фреймворков.
Сценарии использования каждого инструмента
В этом разделе рассмотрим, как инструменты Verify и Storm Petrel применяются на практике. Каждый из них “заточен” под определённые задачи, поэтому важно понимать, в каких случаях и почему стоит выбрать тот или иной вариант.
Первичная и последующая верификация с Verify
Verify хорошо подходит для проектов, где снапшоты предполагается хранить во внешних файлах. С его помощью можно как проверять, так и автоматически обновлять ожидаемые значения в снапшот-тестах. Такой формат удобен, когда нужно разделить тестовую логику и данные, а также просто отслеживать изменения по мере развития проекта.
Пример:
Вы запускаете тест, и результат отличается от сохраненного снапшота — Verify автоматически обновляет его, фиксируя актуальное состояние. Это упрощает контроль изменений и помогает оперативно адаптировать тесты по мере эволюции кода.
Визуализация:
Первичная и последующая верификация с Verify.
Обновление ожидаемых значений в Storm Petrel
Storm Petrel делает упор на хранение ожидаемых данных прямо в коде на C#, но также поддерживает и файл-ориентированные снапшоты. Это делает его универсальным выбором.
У него два основных сценария работы с обновлением ожидаемых значений:
- Классические тесты: Storm Petrel умеет автоматически обновлять ожидаемые значения, записанные прямо в виде C#-кода внутри тестов. Это удобно, если вы предпочитаете держать всё в одном месте, без вынесения снапшотов в отдельные файлы.
Пример:
Когда результат теста меняется, Storm Petrel автоматически подгоняет значение в коде под актуальное состояние.
Визуализация:
Автоматическое обновление baseline в C#-коде.
- Файловые снапшоты:Также Storm Petrel умеет обновлять снапшоты, хранящиеся во внешних файлах. Для этого используется NuGet-пакет FileSnapshotInfrastructure, что позволяет автоматизировать процесс и для более традиционного подхода.
Пример:
Если тест даёт новый результат, Storm Petrel может автоматически обновить соответствующий снапшот-файл.
Визуализация:
Работа с внешними снапшотами через FileSnapshotInfrastructure.
Вердикт: что выбрать?
Выбор зависит от специфики проекта. Если нужно хранить ожидаемые значения прямо в коде, тогда ваш выбор — Storm Petrel. Если же вы предпочитаете внешние файлы для снапшотов, то подойдут оба инструмента — Verify и Storm Petrel. Всё зависит от того, насколько важна для вас настройка, интерактивность и интеграции.
На самом деле, оба решения являются мощными и удобными инструментами для снапшот-тестирования в .NET. Главное отличие между ними — в подходе к хранению и обновлению ожидаемых данных: в коде или через отдельные файлы.