Статья подготовлена Анной anna-che и Ксенией KseMish.

Одной из причин, по которой мы активно взялись за тестирование верстки, стали, как обычно, грабли. Мы с размаху наступили на баг, который стал проявляться после очередного обновления Хрома. Оказалось, что в течение 3-х часов пользователи не могли осуществить перевод средств со счета через личный кабинет нашего интернет-банка. А все из-за того, что в новой версии браузера форма перевода средств с одного счета на другой уехала за пределы окна.

Подобные баги бывают и безобидными. Например, всем известный бренд одежды также наткнулся на эти грабли. Благодаря недостаточному тестированию верстки, пользователи сайта этого бренда вместо кнопки «Узнайте больше» долгое время видели «Узнайте боль…».


Надпись на кнопке, конечно, близка к истине, цены там — реально боль, но это явно не то, что задумывалось создателями сайта. В общем, такие моменты надо отслеживать и исправлять, вне зависимости от того, что они вызывают — неудобство или улыбку.

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

Недолго думая, мы отправились искать варианты, как мы можем минимизировать как количество дефектов верстки, так и противостояний «Фронт VS дизайнер». Изучив возможные практики и инструменты для автоматизации тестирования верстки и насобирав шишек, мы внедрили следующий подход.
Коротко о нас:
Сейчас мы разрабатываем единый продукт, над которым трудятся более 20 скрам-команд, каждая из которых отвечает за определенную функциональность, при этом мы стараемся сохранить единый стиль и дизайн самого продукта — визуальную подачу, расположение основных элементов и т.д.

Относительно распределения пользователей по браузерам, на сегодняшний день наши пользователи используют (значения округлены):

  • 60% — Chrome,
  • 30% — Firefox,
  • 10% — другие браузеры.

Тестируем функциональность мы с помощью нашего BDD-фреймворка Akita (Java + Cucumber + Selenide), о нем мы писали вот тут.
Для начала мы захотели решить проблему с договоренностями между фронтом и дизайнером. На начальном этапе формирования макета функциональности фронт и дизайнер совместно описывают «Контракт». В этом контракте они описывают все договоренности по расположению элементов, их стилей, расстоянию и т.д. Благодаря этому при обнаружении несовпадений макета со сверстанной страницей ребятам не придется долго выяснять, кто прав, а кто виноват.

Описывают они свои договоренности в galen-spec файле.


Что такое galen-spec?


Для того чтобы автоматизировать тестирование верстки и тем самым минимизировать количество дефектов, мы решили внедрить инструмент Galen Framework. В основе него лежит как раз .spec-файл (спецификация или, как мы назвали, «Контракт»). И он легко интегрируется с Selenium-тестами.

После того как дизайнер и фронт составили «Контракт», тестировщик на его основе формирует .spec-файл, согласно требованиям Galen. Фреймворк использует свой собственный язык для написания спецификаций проверок.

Из чего же состоит .spec-файл?

Логически, его можно поделить на две части:

1. object definitions

Тут нам надо обязательно указать, какие объекты есть на нашей странице — header, footer, меню, контент и т.д. В общем, перечисляем основные элементы, которые будем проверять, даем им названия и определяем локаторы.


@objects — элементы на странице (можно использовать CSS, XPATH, ID)

2. Когда определили локаторы, надо определить стили и спецификации конкретных объектов. Для этого используется часть спецификации object specs, где мы подробно описываем, например, что наш блок текста (description-text) находится внутри формы описания, ниже хэдера и содержит определенный текст.


Main section — для каждого описанного элемента в @objects описываются параметры проверки.

* язык galen spec чувствителен к отступам в main section, поэтому обращайте на это особое внимание и соблюдайте табуляцию :)

Таким образом, «Контракт», заключенный между фронтом и дизайнером и перенесенный на язык Galen, позволяет нам автоматизировано проверить расположение и внутреннее содержание элементов, а также адаптивность и кроссбраузерность.

Пример быстрого старта



  1. Описываем элементы конкретной страницы и проверки в файлах .spec, используя язык Galen Spec, и кладем в пакет specs.
  2. Эталонные скриншоты складываем в пакет specs/images
  3. Мы работаем по BDD, поэтому сценарий в .feature-файле может выглядеть примерно вот так:

  4. Запускаем тестовый сценарий через обычный Cucumber Runner.

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

Разница в отчетах выглядит следующим образом:


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)


  1. Sabubu
    27.02.2019 00:55
    +2

    Какие я вижу недостатки:

    — хотелось бы более гибкую спецификацию, позволяющую писать более общие правила вроде «расстояние между полями от X до Y% от высоты поля, контрастность текста на кнопке не менее Z%, длина строки текста не более W символов, строки текста не накладываются, не перекрыты непрозрачными элементами».

    — вы прописываете в спецификацию куски CSS кода (ширина, высота), делая ее довольно бессмысленной. Плюс, непонятно зачем указывать размеры при наличии картинки-образца.

    — сравнение через скриншоты не отличает незначительных изменений от значительных. Шрифт рендерится по-другому, слово стало на 2 пикселя шире и текст перенесся на новую строку — огромное количество расхождений. В выпадающем списке пропал треугольничек — незначительная мелочь. Мне кажется, это в нынешнем виде тупиковая технология.

    — страшная смесь кирилицы и латиницы в спецификации

    — какой-то велосипедный синтаксис в спецификации, напоминает yaml, но не yaml

    — непонятно, как переносить длинные строки в спецификации

    — вместо «совершен переход на страницу...» лучше, по моему, писать «мы на гитхабе» в целях повышения скорости чтения и написания кода

    — селекторы вроде ".d-md-flex h1" ужасные. Ну это же явно стили, отвечающие за внешний вид, а не за назначение.

    — для поиска обрезающегося текста скриншоты не подходят, так как у вас может быть 20 локализаций и только в одной текст обрезается. Тут наверно нужно решение, заточенное специально под поиск таких ситуаций (сравнить кол-во символов в дереве DOM и видимых на экране).


    1. anna-che
      27.02.2019 13:25

      Вы путаете gherkin сценарии и galen spec)
      А если познакомитесь с документацией galen framework, увидите, что он использует специальный galen spec language похожий на yaml для описания требований к отображению элементов. И у него своя специфика и требования к описанию тех самых spec файлов.
      По поводу более гибкой спецификации, ничего не мешает написать свой шаг, который будет проверять нужные Вам стили элементов, расстояния и т.д.
      По поводу сравнения картинок по пикселям согласна, там есть подводные камни, о которых более подробно я рассказывала на Selenium Camp. Из решений на рынке, не использующих ML, galen на текущий момент лучший инструмент, который можно интегрировать со своими Selenium тестами.


      1. PerlPower
        27.02.2019 14:31

        А что за решения на базе ML и насколько они гибкие?


        1. anna-che
          28.02.2019 17:03

          Есть applitools.com Они используют AI для сравнения изображений. Гибкие, удобные, с Selenium тестами интегрируются но заставляют в своей экосистеме жить и стоят денег)


  1. Spaceoddity
    27.02.2019 10:27

    А все из-за того, что в новой версии браузера форма перевода средств с одного счета на другой уехала за пределы окна.

    Может просто стоит делать нормальную вёрстку? Мне крайне сложно представить «баг» обновления браузера, который сломает лэйаут страницы.
    Пообмажутся своими фреймворками…


    1. anna-che
      27.02.2019 13:27

      Можно код без багов писать, чего там сложного


    1. iketari
      27.02.2019 13:28

      Ну почему же. Недавний Chrome 72 «исправил» флексы слегка в соответсвии со спецификацией и сломался как раз таки лэйаут.


      1. Spaceoddity
        01.03.2019 13:32

        Если вам нужен «пуленепробиваемый скелет», то это явно не про флексбоксы. Вы ещё гриды предложите.


  1. dariaamir
    27.02.2019 10:31

    Отличная статья, интересный метод, спасибо.
    А можно через эту же методику локализацию тестировать? Например, что вёрстка не поползёт, если мы изменим язык системы на немецкий или китайский?


    1. anna-che
      27.02.2019 13:35

      Спасибо) конечно можно. Описываете требования к отображению элементов в spec файле и просто дергаете проверку соответствия страницы после переключения на нужный язык. Все это с шагами теста можно интегрировать. Если сравнивать какие-то части страницы по скриншотам, есть вероятность, что их может быть много для разных языков. а так проверку для нескольких похожих скриншотов можно в spec файле в одну строчку реализовать: image file images/registration-form—*.png. Galen в данном случае будет по очереди сравнивать нужный элемент со скриншотами, название которых начинается на registration-form, пока не найдет подходящий