Тестируем вёрстку правильно

Makeup — инструмент для комфортного ручного регрессионного тестирования вёрстки

Что не так с тестированием вёрстки


Мы часто им пренебрегаем. Написание функциональных, интеграционных и юнит-тестов давно стало повсеместной практикой. Вёрстке мы обычно уделяем гораздо меньше времени.

Проблема тестирования вёрстки в том, что только живой человек может сказать, хорошо свёрстан блок на странице или нет. Поэтому чаще всего мы тестируем HTML и CSS вручную: проверяем, как будет вести себя блок, если в нем будет слишком много (или слишком мало) текста или дочерних элементов; смотрим, чтобы все возможные варианты отображения блока смотрелись корректно; помним о том, как блоки должны адаптироваться к разным устройствам и разрешениям экрана.

Как тестировать вёрстку правильно


Нам не нужно придумывать ничего нового. Мы можем применить те же подходы, которые используем при написании автотестов.

Сначала нужно посмотреть на требования, дизайн. На основе этого составить список всех значимых состояний приложения, которые нужно проверить. Далее, дело за малым — проверить каждый тест-кейс.

В статье я расскажу, как мы создали для себя Makeup, как изменили свой процесс разработки интерфейсов и как это упростило нам жизнь.

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

Описанный подход может помочь, если на вашем проекте соблюдаются 2 условия:

  • у вас есть эталонные дизайн для всех блоков, и вы хотите, чтобы ваш проект точно соответствовал этому дизайну;
  • вы придерживаетесь BEM-методологии в HTML и CSS.


А теперь обо всём по порядку.

Как измерить качество вёрстки


Первая версия Makeup (тогда у него ещё не было имени) возникла в файле spec/index.html. На этой странице прогонялись юнит-тесты по всем модулям (читай: блокам) нашего приложения. Всё было традиционно: мы инициализировали каждый модуль с разными наборами тестовых данных и проверяли тестами то, что нас интересовало.

Но этого было недостаточно. Несмотря на то, что эти тесты были сильно связаны с вёрсткой, они не могли ответить на вопрос, хорошо ли свёрстан модуль и правильно ли он будет вести себя в разных обстоятельствах.

В сети можно найти огромное количество чек-листов на качество вёрстки. Проверку многих пунктов из них можно легко поручить анализаторам кода. Но обычно эти чек-листы проверяют качество работы по косвенным или нерелевантным признакам.

По большому счету, критериев качества вёрстки всего два:

  • соответствие макету: вёрстка должна быть идентична дизайну.
  • работоспособность: вёрстка должна отображаться в браузере пользователя на всех устройствах, которые нас интересуют.


При несоблюдении любого из двух пунктов проделанная работа не имеет никакого смысла.

Как проверить соответствие макету


Сравнить вёрстку с исходным макетом и найти отличия. Но это порой не так просто. Помните, в детских журналах были головоломки «найди 10 отличий»?

5de7753525af4e349426d9e4c0179833.png

Любой инженер мгновенно предложит очевидное решение, как проще находить отличия. Достаточно наложить одно изображение на другое и верхнее изображение сделать полупрозрачным.

Можно сделать ещё удобнее — инвертировать цвета для верхнего полупрозрачного изображения. Тогда при идеальном совпадении мы должны увидеть однородный серый фон.

1698daaceb714d2ab6f3d42229e93fd0.png

Зачем для этого специальный инструмент


Для реализации подобной задумки не нужен специальный инструмент. Если нужно сравнить вёрстку с исходным дизайном страницы сайта, то такой подход можно реализовать прямо в браузере.

1. Добавляем картинку с макетом




2. Позиционируем поверх свёрстанной страницы

#psd {
        /* Позиционируем макет */
        position: absolute;
        top: 0;
        left: 50%;
        margin: 0 0 0 -640px;

        /* Делаем его полупрозрачным */
        opacity: .5;

        /* Оставляем возможность взаимодействия с элементами */
        pointer-events: none;

        /* Инвертируем изображение в вашем любимом -webkit (-blink) браузере */
        -webkit-filter: invert(100%);
        }
body:hover #psd {
        /* Прячем картинку при наведении */
        opacity: 0;
        }


По такому принципу работает огромное количество существующих инструментов:

  • JavaScript-плагины
    • Resemble.js
  • Расширения для браузера
    • PerfectPixel
    • 1 px


При желании вы найдёте ещё несколько десятков или сотен таких инструментов.

В чём же проблема


Этот подход применим только в том случае, когда при разработке мы можем построить однозначное соответствие между макетами и страницами верстки.

dc54f7477ee3401db49de8d503c23a42.jpg
На деле мы всё чаще работаем со сложными веб-приложениями. И обычно мы не используем термин «страница». В привычных нам терминах веб-приложение с точки зрения вёрстки состоит из произвольного набора BEM-блоков и их состояний.

b63205bbddf44b63835aeffcd5efd31e.jpg

Состояние блока — это его конечное отображение при определенном наборе элементов, модификаторов и при определенном контенте. Другими словами, каждое состояние блока — это один кейс его использования.

На практике это значит, что если, к примеру, у вас на проекте всего 100 независимых блоков, и для каждого из них предусмотрено всего 10 значимых кейсов использования, то вам придется помнить о 1000 уникальных состояний вашего приложения.

Можно разбивать вёрстку на блоки поменьше, уменьшая количество состояний в каждом, но порядок числа вряд ли сильно изменится.

1000 состояний — это очень много. Ни один человек не в состоянии удержать всё это в голове. И тем более быть уверенным в качестве вёрстки каждого блока.

Как я делал раньше


Раньше при разработке сложных блоков с большим количеством состояний для сравнения верстки отдельного блока с дизайном я использовал невероятно медленный способ.

  • ⌘ + Shift + Control + 4 выделяем область страницы с блоком, делаем скриншот в буфер обмена
  • ⌘ + Tab перемещаемся в соседнюю вкладку с Фотошопом
  • ⌘ + v вставляем скриншот
  • ⌘ + 5 выставляем слою прозрачность 50%
  • v выбираем инструмент Move Tool
  • Shift + Arr или Arr × n раздвигаем до тех пор, пока точно не совместим с макетом
  • Delete


После этого правим CSS и повторяем всю последовательность заново. Пока макет не станет идеальным.

Эту последовательность можно научиться выполнять по-настоящему быстро, но процесс всё равно будет занимать огромное количество времени. Но такой подход никогда не даст уверенности при регрессии или рефакторинге. Да и заниматься подобной ерундой не хочется.

Как мы сделали ещё один инструмент


Мы не нашли инструмент, который бы нам позволил в любой момент времени…

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


Поэтому мы решили сделать для себя Makeup.

Сначала мы добавили сравнение с дизайном на страницу с юнит-тестами. Затем добавили пару ползунков для управления отображением блоков. А со временем всё это переросло в отдельный интерфейс, который стал основой рабочего процесса разработки интерфейсов в нашей команде.

4e1fdd5a7c4f432aac1ce57747a15160.png
На этой иллюстрации почти все возможности Makeup. Это невероятно простой инструмент.

Что нужно для реализации


  • Ресурсы вашего приложения: шаблоны (или просто HTML), стили, JavaScript-код, графику — всё, что есть в вёрстке.
  • Изображения с исходным дизайном блоков в различных состояниях.
  • Конфигурационный файл, который покажет «Makeup», каким образом всё перечисленное можно связать воедино.


808324d007ed43cc9d4ba97ac9cdb19b.jpg

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

Наша команда почти полностью собирает конфигурацию автоматически на основе имеющихся тестовых данных. Вручную остается дописать только «заплатки» стилей, сниппеты и ссылки на документацию. На этапе сборки приложения формируются все необходимые конфигурационные файлы и создаётся отдельный порт, на котором запущен Makeup.
4baa09757dba4bcd892556acdae16db3.jpg

Как можно использовать


В нашей команде Makeup — основа разработки интерфейса приложения. Мы активно используем его на всех этапах жизни блока.

  1. Разработка. При разработке блока с нуля, нужен исходный дизайн, продуктовые требования и изолированная среда для разработке. Удобно, когда это оказывается под рукой в одном интерфейсе.
  2. Код-ревью. Когда смотришь на чужую работу, нужно быстро увидеть перечень изменений; сверить результаты с продуктовыми требованиями и дизайном; проверить работоспособность всех кейсов использования блока.
  3. Рефакторинг. При рефакторинге существующего блока нужно быстро увидеть весь блок и все его возможные состояния. Иногда состояний бывает много, и некоторые из них совсем не очевидные. После внесения изменений, важно проверить, что ничего не сломано.


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

Если своевременно добавлять все необходимые тест-кейсы и использовать Makeup на всех этапах разработки, можно спать спокойно — никаких неожиданных неприятностей ваша вёрстка вам не принесет.

Как подобрать тест-кейсы


В начале статьи я использовал термин «значимые состояния». Пора рассказать о том, как мы в работе выбираем значимые кейсы и как пытаемся обеспечить хорошее покрытие для вёрстки.

Мы пришли к выводу, что достаточно фиксировать 3 типа состояний.

  • Состояния, описанные в дизайне.
    Если дизайнер подготовил макет, в котором нарисовал блок в 4 разных состояниях, нам нужно описать все эти состояния для Makeup.
  • Состояния, которые вызвали баг в прошлом
    Если на проекте появляется баг, связанный с вёрсткой, его недостаточно просто починить. Хорошим тоном считается написать тест на этот баг. Мы в этом случае ещё сохраняем в Makeup кейс, в котором вопроизводился баг. Тогда при рефакторинге блока, когда разработчик проверит все состояния блока, он может быть уверен, что этот баг не воспроизводится.
  • Экстремальные состояния
    Экстремальными состояниями мы называем те, в которых чаще всего ломается вёрстка: длинные тексты (которые могут ещё и не содержать пробелов), отсутствие элементов в блоке и другие.


Можем ли мы перестать тестировать вёрстку руками


Если нам важно точное соответствие исходному дизайну, к сожалению, нет. Но в наших силах сделать тестирование вёрстки комфортным, быстрым и надежным.

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

А как тестируете вёрстку вы?

© Habrahabr.ru