![](https://habrastorage.org/webt/ve/hr/xz/vehrxzet4vk1c2wtj-apbx6j8xq.png)
Статья подготовлена Анной anna-che и Ксенией KseMish.
Одной из причин, по которой мы активно взялись за тестирование верстки, стали, как обычно, грабли. Мы с размаху наступили на баг, который стал проявляться после очередного обновления Хрома. Оказалось, что в течение 3-х часов пользователи не могли осуществить перевод средств со счета через личный кабинет нашего интернет-банка. А все из-за того, что в новой версии браузера форма перевода средств с одного счета на другой уехала за пределы окна.
Подобные баги бывают и безобидными. Например, всем известный бренд одежды также наткнулся на эти грабли. Благодаря недостаточному тестированию верстки, пользователи сайта этого бренда вместо кнопки «Узнайте больше» долгое время видели «Узнайте боль…».
![](https://habrastorage.org/webt/ji/t8/_f/jit8_fp2oqk4f1jtrrq2vho-bgg.png)
Надпись на кнопке, конечно, близка к истине, цены там — реально боль, но это явно не то, что задумывалось создателями сайта. В общем, такие моменты надо отслеживать и исправлять, вне зависимости от того, что они вызывают — неудобство или улыбку.
Осознавая эти проблемы, мы применили практику обязательного design review со стороны наших продуктовых дизайнеров, но не тут-то было. Оказалось, что не во всех командах есть выделенный дизайнер, или у них не хватает времени, или, что еще страшнее, фронт и дизайнер не могут прийти к общему подходу к верстке той или иной страницы, формы или элемента.
Недолго думая, мы отправились искать варианты, как мы можем минимизировать как количество дефектов верстки, так и противостояний «Фронт VS дизайнер». Изучив возможные практики и инструменты для автоматизации тестирования верстки и насобирав шишек, мы внедрили следующий подход.
Коротко о нас:Для начала мы захотели решить проблему с договоренностями между фронтом и дизайнером. На начальном этапе формирования макета функциональности фронт и дизайнер совместно описывают «Контракт». В этом контракте они описывают все договоренности по расположению элементов, их стилей, расстоянию и т.д. Благодаря этому при обнаружении несовпадений макета со сверстанной страницей ребятам не придется долго выяснять, кто прав, а кто виноват.
Сейчас мы разрабатываем единый продукт, над которым трудятся более 20 скрам-команд, каждая из которых отвечает за определенную функциональность, при этом мы стараемся сохранить единый стиль и дизайн самого продукта — визуальную подачу, расположение основных элементов и т.д.
Относительно распределения пользователей по браузерам, на сегодняшний день наши пользователи используют (значения округлены):
- 60% — Chrome,
- 30% — Firefox,
- 10% — другие браузеры.
Тестируем функциональность мы с помощью нашего BDD-фреймворка Akita (Java + Cucumber + Selenide), о нем мы писали вот тут.
Описывают они свои договоренности в galen-spec файле.
![](https://habrastorage.org/webt/xo/7g/02/xo7g02bazkdk9vuzt9py7a8r25i.png)
Что такое galen-spec?
Для того чтобы автоматизировать тестирование верстки и тем самым минимизировать количество дефектов, мы решили внедрить инструмент Galen Framework. В основе него лежит как раз .spec-файл (спецификация или, как мы назвали, «Контракт»). И он легко интегрируется с Selenium-тестами.
После того как дизайнер и фронт составили «Контракт», тестировщик на его основе формирует .spec-файл, согласно требованиям Galen. Фреймворк использует свой собственный язык для написания спецификаций проверок.
Из чего же состоит .spec-файл?
Логически, его можно поделить на две части:
1. object definitions
Тут нам надо обязательно указать, какие объекты есть на нашей странице — header, footer, меню, контент и т.д. В общем, перечисляем основные элементы, которые будем проверять, даем им названия и определяем локаторы.
![](https://habrastorage.org/webt/wk/p3/qw/wkp3qwgrloe9mudmze4s5onbhas.png)
@objects — элементы на странице (можно использовать CSS, XPATH, ID)
2. Когда определили локаторы, надо определить стили и спецификации конкретных объектов. Для этого используется часть спецификации object specs, где мы подробно описываем, например, что наш блок текста (description-text) находится внутри формы описания, ниже хэдера и содержит определенный текст.
![](https://habrastorage.org/webt/sg/p5/yv/sgp5yvsy8ivk1klbpblxrkwloc4.png)
Main section — для каждого описанного элемента в @objects описываются параметры проверки.
* язык galen spec чувствителен к отступам в main section, поэтому обращайте на это особое внимание и соблюдайте табуляцию :)
Таким образом, «Контракт», заключенный между фронтом и дизайнером и перенесенный на язык Galen, позволяет нам автоматизировано проверить расположение и внутреннее содержание элементов, а также адаптивность и кроссбраузерность.
Пример быстрого старта
![](https://habrastorage.org/webt/jd/iz/i6/jdizi6elmbwl6khngbv4tixgrxg.png)
- Описываем элементы конкретной страницы и проверки в файлах .spec, используя язык Galen Spec, и кладем в пакет specs.
- Эталонные скриншоты складываем в пакет specs/images
- Мы работаем по BDD, поэтому сценарий в .feature-файле может выглядеть примерно вот так:
- Запускаем тестовый сценарий через обычный Cucumber Runner.
В данном сценарии мы проверяем главную страницу GitHub. В последнем шаге добавили проверку верстки. Подобными проверкам можно дополнять существующие функциональные тесты, или же запускать их отдельно. Если в верстке обнаруживаются какие-то несовпадения, то у нас будет изображение с ожидаемым результатом и с полученным, плюс с разницей в них. Все это дело приаттачится к кукумбер-отчету.
Разница в отчетах выглядит следующим образом:
![](https://habrastorage.org/webt/vd/si/3y/vdsi3yuoje6lkl3fkl74ydyczzo.png)
error=Error{[Element does not look like «./akita-testing-template/src/test/resources/specs/images/registration-form.png». There are 10,47% mismatching pixels but max allowed is 10%]
Здесь видим, что проверка не прошла, изображения отличаются более чем на 10% и все эти цветные различия, кроме заливки черным цветом, это и есть разница между элементами.
Если элементы полностью идентичны, разница будет отображаться черным цветом.
Самый частый вопрос, где вообще взять эталонный скриншот?
Ответ: Эталон мы берем либо у дизайнера, либо прогоняя тесты на продовском окружении, которое считаем эталонным. Получаем оттуда картинки наших блоков, которые будем сравнивать, и кладем их в папочку images, откуда спецификации будут выдергивать на них ссылки.
К чему мы пришли, используя этот подход
- сумели снизить количество смоук-тестов и время их прохождения примерно на 20% за счет того, что проверку некоторых форм и подобных элементов схлопнули в один тест, который проверяет их визуальную составляющую и сразу выявляет расхождения
- теперь можем быть уверены в том, что наши приложения отображаются корректно в выбранных браузерах
- знаем, что адаптивность в порядке, а не разъехалась
- пришли к автоматическому дизайн-ревью.
Почитать документацию по составлению galen-spec файлов можно тут — galen-spec-language-guide.
О технических аспектах работы с Galen Framework, его возможностях и основных проверках мы рассказали на прошедшем Selenium Camp, и еще напишем в блоге.
Возможность использовать galen-spec и новые шаги по проверке верстки мы вынесли в нашу библиотеку Akita, где есть шаблон для быстрого старта, а также мы ведем телеграм-чатик, где вы можете задать интересующие вас вопросы.
А мы обязательно ответим.
Комментарии (10)
Spaceoddity
27.02.2019 10:27А все из-за того, что в новой версии браузера форма перевода средств с одного счета на другой уехала за пределы окна.
Может просто стоит делать нормальную вёрстку? Мне крайне сложно представить «баг» обновления браузера, который сломает лэйаут страницы.
Пообмажутся своими фреймворками…iketari
27.02.2019 13:28Ну почему же. Недавний Chrome 72 «исправил» флексы слегка в соответсвии со спецификацией и сломался как раз таки лэйаут.
Spaceoddity
01.03.2019 13:32Если вам нужен «пуленепробиваемый скелет», то это явно не про флексбоксы. Вы ещё гриды предложите.
dariaamir
27.02.2019 10:31Отличная статья, интересный метод, спасибо.
А можно через эту же методику локализацию тестировать? Например, что вёрстка не поползёт, если мы изменим язык системы на немецкий или китайский?anna-che
27.02.2019 13:35Спасибо) конечно можно. Описываете требования к отображению элементов в spec файле и просто дергаете проверку соответствия страницы после переключения на нужный язык. Все это с шагами теста можно интегрировать. Если сравнивать какие-то части страницы по скриншотам, есть вероятность, что их может быть много для разных языков. а так проверку для нескольких похожих скриншотов можно в spec файле в одну строчку реализовать: image file images/registration-form—*.png. Galen в данном случае будет по очереди сравнивать нужный элемент со скриншотами, название которых начинается на registration-form, пока не найдет подходящий
Sabubu
Какие я вижу недостатки:
— хотелось бы более гибкую спецификацию, позволяющую писать более общие правила вроде «расстояние между полями от X до Y% от высоты поля, контрастность текста на кнопке не менее Z%, длина строки текста не более W символов, строки текста не накладываются, не перекрыты непрозрачными элементами».
— вы прописываете в спецификацию куски CSS кода (ширина, высота), делая ее довольно бессмысленной. Плюс, непонятно зачем указывать размеры при наличии картинки-образца.
— сравнение через скриншоты не отличает незначительных изменений от значительных. Шрифт рендерится по-другому, слово стало на 2 пикселя шире и текст перенесся на новую строку — огромное количество расхождений. В выпадающем списке пропал треугольничек — незначительная мелочь. Мне кажется, это в нынешнем виде тупиковая технология.
— страшная смесь кирилицы и латиницы в спецификации
— какой-то велосипедный синтаксис в спецификации, напоминает yaml, но не yaml
— непонятно, как переносить длинные строки в спецификации
— вместо «совершен переход на страницу...» лучше, по моему, писать «мы на гитхабе» в целях повышения скорости чтения и написания кода
— селекторы вроде ".d-md-flex h1" ужасные. Ну это же явно стили, отвечающие за внешний вид, а не за назначение.
— для поиска обрезающегося текста скриншоты не подходят, так как у вас может быть 20 локализаций и только в одной текст обрезается. Тут наверно нужно решение, заточенное специально под поиск таких ситуаций (сравнить кол-во символов в дереве DOM и видимых на экране).
anna-che
Вы путаете gherkin сценарии и galen spec)
А если познакомитесь с документацией galen framework, увидите, что он использует специальный galen spec language похожий на yaml для описания требований к отображению элементов. И у него своя специфика и требования к описанию тех самых spec файлов.
По поводу более гибкой спецификации, ничего не мешает написать свой шаг, который будет проверять нужные Вам стили элементов, расстояния и т.д.
По поводу сравнения картинок по пикселям согласна, там есть подводные камни, о которых более подробно я рассказывала на Selenium Camp. Из решений на рынке, не использующих ML, galen на текущий момент лучший инструмент, который можно интегрировать со своими Selenium тестами.
PerlPower
А что за решения на базе ML и насколько они гибкие?
anna-che
Есть applitools.com Они используют AI для сравнения изображений. Гибкие, удобные, с Selenium тестами интегрируются но заставляют в своей экосистеме жить и стоят денег)