Недавно я выступал с докладом на мероприятии сообщества BerlinJS, где хотел поделиться своим недавним опытом тестирования снимков. Несомненно, вы слышали этот термин с тех пор, как он недавно стал популярен в среде тестирования Jest.
Подход к тестированию снимков не является чем-то новым. Впервые я услышал об этом в известной книге М. Фезерса Работа с устаревшим кодом. Подход символьного тестирования нашел у меня отклик, поскольку он прост и идеально подходит для тестирования сложных систем. Однако на тот момент не было хороших инструментов, которые позволили бы легко интегрировать этот подход в процесс разработки.
Позже Ллевеллин Фалько выпустил свою структуру Approval Testing. С моей точки зрения, это был первый подход, позволивший улучшить UX при тестировании снимков.
Давайте немного поговорим об основах тестирования моментальных снимков и увидим, что его применение выходит далеко за рамки простого тестирования компонентов React.
Государство и представительство
При тестировании снимков все сводится к пониманию состояния системы и представления состояния (выходных данных системы).
В зависимости от типа системы у вас есть разные понятия для состояния и представления, чтобы сделать его немного более ясным, я бы попытался описать его для трех разных ролей разработчиков - внешнего интерфейса, внутреннего интерфейса и мобильного.
Front-end люди
В случае приложения на основе Redux состояние - это состояние Redux. Итак, это один большой объект, который содержит значения всех элементов управления пользовательского интерфейса и данные, поступающие с сервера. Если вы используете шаблон MVC для создания приложений, состояние вашего приложения - это комбинация моделей, которые поддерживает приложение.
Представлением состояния является фактический код HTML / CSS (например, созданный React), который отображается браузером как пользовательский интерфейс приложения.
Back-end люди
Очень часто состояние системы представляет собой комбинацию баз данных, памяти, файлов и других служб, к которым система имеет доступ. Итак, все входы / выходы участвуют в поведении системы, формируя ее состояние.
Представление состояния - JSON / HTML / XML или любой другой формат, в котором конечная точка отвечает.
Мобильные люди
Я думаю, это очень похоже на интерфейс, где состояние - это модель (или набор моделей), которую приложение хранит в памяти (или в локальных хранилищах, на основе ключа-значения или на основе SQL).
Состояние отображается в пользовательском интерфейсе, отображаемом мобильной платформой.
Суть тестирования снимков
По сути, тестирование снимков - это способность «заморозить» состояние и получить представление системы (снимок), сериализованное в форме, удобной для компьютеров и людей.
Если система изменилась, мы делаем следующий снимок и сравниваем его с предыдущим.
Если снимки разные, тест станет «красным». Мы решаем, является ли разница «правильным» или «неправильным», и либо «одобряем» следующий снимок, либо исправляем проблему, вызывая регресс.
Позвольте мне объяснить формулу немного подробнее,
f()
- функция, поведение системы;
State
- состояние, данные, поступающие в систему на входе;
R
- представление вывода системы;
Самая важная вещь для тестирования моментальных снимков - это иметь возможность получить представление в форме, которую легко понять (прочитать) и сравнить с предыдущим состоянием (diff).
Читаемость
Несмотря на модульное тестирование с утверждениями, где вы выражаете ожидаемый результат как,
expect(result).toEqual(something);
Со снимками вы не знаете, что такое «что-то». Однако вы видите, как «это похоже». Поскольку вы должны сделать вывод, правильно ли представление снимка или нет, его удобочитаемость становится решающей.
Способность различать
В то же время формат представления должен быть пригоден для разграничения.
Итак, вот и проблема,
Чем лучше читаемый формат, тем меньше он несовместим с другими.
Давайте рассмотрим пару примеров.
1. У нас есть система бухгалтерской отчетности, которая представляет собой базу данных со всеми счетами-фактурами, расходами, клиентами и т. Д., А на выходе получается файл PDF для годового отчета. PDF-файл легко читать, но, поскольку это двоичный формат, трудно различать и, кроме того, понять, что именно изменилось, прочитав разницу.
2. У нас есть веб-приложение с набором различных компонентов на экране, мы можем представить состояние как реальный HTML-код, который идеально подходит для различий, но наш мозг не является браузером, поэтому сложно визуализировать этот HTML-код в уме, поэтому даже если мы сможем его прочитать, то трудно сделать вывод, что он «выглядит» правильно.
Поэтому важно поддерживать правильный баланс между этими двумя свойствами.
К счастью, на практике мы имеем дело с простыми представлениями небольших файлов JSON или HTML, которые легко понять и сравнить.
Преимущества тестирования снимков
- Как я упоминал выше, подход к тестированию более простой со снимками состояния. Да, это больше не метод «сначала тестирование», а метод «тестирование после». Вы пишете код; вы проверяете это; вы получаете представление и замораживаете его до следующего тестового прогона.
- Он подходит для сложных представлений в виде больших выходных данных JSON и HTML, поэтому вместо сотен
assert()
вызовов у вас есть один.toMatchSnapshot()
вызов. - Снимок становится визуализацией изменений кода. В рамках базы кода и запросов на вытягивание вы сразу видите, что делают изменения кода, просматривая изменения в моментальных снимках.
Слайды этого выступления доступны здесь:
https://speakerdeck.com/alexbeletsky/snapshot-testing-going-beyond-ui
Если вас интересует тестирование снимков с помощью Mocha, ознакомьтесь с моей предыдущей статьей: