Количество просмотров81
3 октября 2022

Fluent Assertions — инструмент автоматизированного тестирования

Проверки в автотестах являются обязательным компонентом, так как основная задача любого теста сравнить ожидаемый результат с фактическим. Меня зовут Вадим, я специалист по тестированию, и в этой статье я хочу уделить внимание одной из частей любого автотеста – Assert. Казалось бы, какие трудности могут возникнуть с этим, на первый взгляд, простым компонентом любого автотеста? На одном из своих проектов я столкнулся с большим количеством автотестов, проблемой которых как раз и были неверно написанные проверки. Хочу рассказать о причинах возникновения этих трудностей и поделиться путём решения проблемы, который мне удалось пройти вместе с командой. 

Проблемы автотестов

Я подключился к проекту, когда 12000 автотестов уже были написаны, а ещё несколько тысяч ожидали своего написания. Команда Auto QA погрязла в изучении логов упавших тестов в CI/CD. Основной проблемой, почему на это уходила масса времени, была неинформативность ошибок. Использовалась стандартная библиотека Assert’ов, и тест, написанный с её использованием, выдавал ошибку, по которой было очень тяжело диагностировать что-либо, не заглядывая в код.

Пример теста:

Пример теста

Пример ошибки:

Пример ошибки

Сперва было принято неверное решение, которое помогло решить данную проблему, но породило другую. Мы начали добавлять сообщения в Assert’ы.

Пример кода:

Пример ошибки:

Проблема, которая возникла при таком подходе — огромная длительность и трудоёмкость при написании новых тестов и поддерживании старых. Особенность проекта — команда распределена по всему миру, а потому английский у людей был разного уровня, и многие сообщения были написаны без использования общепринятых норм. Проблема неинформативности переродилась и сохранилась уже в другом виде.

Плюсы библиотеки Fluent Assertions

Решить эти проблемы нам помогла библиотека Fluent Assertions. Основным плюсом библиотеки является простота её использования: формат написания проверки субъект -> действие -> объект более привычен для людей. Другим плюсом является информативность сообщений, который встроены по умолчанию.

Наш старый пример, но с использованием Fluent Assertions, строка 26:

Пример ошибки:

Как можно заметить, при хорошо подобранном названии переменных не составляет труда понять по ошибке, что конкретно случилось. Очевидным плюсом является огромный функционал этой библиотеки, которому я нашел много полезных применений.

Функционал библиотеки

К базовому функционалу, который выполняет стандартные функции, можно отнести следующие Assert’ы:

Стоит отметить, что большинство проверок в библиотеке имеют свою противоположность со словом Not в начале. 

На первых этапах перевода проекта на Fluent Assertions я вместе с командой заменял Assert’ы из стандартной библиотеки на эти базовые проверки. 

Особое внимание хочется обратить на конструкцию AssertionScope. Эта конструкция позволяет объединить несколько проверок в 1 блок, который осуществит их одновременное выполнение. Почему этой конструкции уделено особое внимание в этой статье?

Время выполнения 1 автотеста на проекте варьировалось от 5 до 15 минут. При проверке упавшего автотеста хочется убедиться, что не только причина падения была исправлена, но и последующие проверки в том же тесте проходят без проблем. Без использования этой конструкции алгоритм работы с упавшим тестом выглядит так:

  1. Исправление проблемы, из-за которой тест падает;
  2. Тестовый запуск с возможным нахождением другой проблемы в последующих проверках;
  3. Если проблема далее найдена, то возвращаемся к пункту 1.

Таким образом ситуация с N проверок может растянуть исправление автотеста до N*t, где t — время запуска этого теста. Именно здесь на помощь приходит AssertionScope.

Пример использования AssertionScope:

Пример ошибок:

Как мы видим, после падения теста на первой проверке, тест проверил и вторую конструкцию и обнаружил, что там тоже возникает проблема.

Отдельное внимание я уделю измерению времени, которое позволяет выполнить данная библиотека. 

Пример:

Эта функциональность нашла применение на нашем проекте в части бесконечных алертов, которыми было наполнено наше приложение. С помощью этой возможности мы с лёгкостью интегрировали замеры времени между различными событиями. Кстати, время и дату Fluent Assertions позволяет записать на более удобном для чтения и восприятия языке.

Пример сравнения даты, записанной в переменную DateTime с использованием конструктора (34 строка), и даты, записанной с использованием Fluent Assertions (37 строка):

Конечно, библиотека позволяет не просто сравнивать даты, но и определять разницу между ними:

Очень просто начать работать с этой библиотекой. Для этого её нужно просто установить через NuGet Package Manager, а потом в нужном классе прописать using FluentAssertions;

Немного о цифрах

Для интеграции этого решения в проект и замены старого функционала на Fluent Assertions в проблемных тестах у нас, команды из 4 человек, ушло 2 недели. В следующие полтора месяца внедрение библиотеки коснулось оставшихся тестов. Менее чем через квартал мы вышли на написание новых тестов и расширения нашего тестового проекта. Сейчас, придя на новый проект с гораздо меньшим количеством тестов, я сразу предложил использовать Fluent Assertions и очень быстро обновил все тесты. 

Заключение

1) Fluent Assertions позволяют читать код как книгу на английском языке. В большинстве случаев не нужны громоздкие, трудно поддерживаемые сообщения.

2) Fluent Assertions позволяют более просто диагностировать проблему прямо при чтении результатов в CI. Это очень полезно при масштабных тестах, запуск которых лишний раз потратит кучу времени тестировщика.

3) При составлении новых автотестов Fluent Assertions позволяют с лёгкостью использовать уже написанные куски кода, т. к. не составляет труда лишний раз понять, что там написано.

Спасибо за то, что уделили время прочтению статьи. В комментариях можете поделиться своим опытом использования Fluent Assertions.