Verify против Storm Petrel: плюсы и минусы

На рынке существует много хороших инструментов для снапшот-тестирования в .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

Работа с файловыми снапшотами в 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",
        }
    });
}

Снапшот-тест в стиле Verify:

[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

Ниже приведены ключевые преимущества и недостатки каждого подхода (хотя этот список не является полным).

baseline в C#-коде.

Плюсы Verify:

Минусы 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. Главное отличие между ними — в подходе к хранению и обновлению ожидаемых данных: в коде или через отдельные файлы.

Свяжитесь с нами

Мы любим новые проекты! Напишите нам, и мы ответим вам в ближайшее время.

Спасибо, что написали нам! Ваше сообщение было успешно отправлено. Мы обязательно ответим на него в ближайшее время. Пожалуйста, проверьте, получили ли Вы от нас письмо-подтверждение на указанную Вами почту.