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

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

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


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

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

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


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

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

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

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

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

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

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

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


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

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

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

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

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

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

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


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



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

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



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


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

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


    <img src="index.png" width="1280" height="2000" id="psd">
    

    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
      • 1px

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

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


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


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



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

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

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

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

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


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

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

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

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

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


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

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

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

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


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

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


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



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

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


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


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

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

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

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

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


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

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

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

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


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

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

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

    Ссылки


    Метки:
    2ГИС 295,78
    Карта города и справочник предприятий
    Поделиться публикацией
    Комментарии 31
    • +1
      как было бы хорошо протестировать верстку с помощью вашего makeup`а
      • +4
        Что вас останавливает?
        • +2
          прошу прощения. ссылку не заметил.
          • +1
            Я тоже не заметил ссылку.
            • 0
              Продублируй её в конце статьи.
              • +1
                Готово, теперь в статье есть все явки.
          • +7
            Ну это не совсем тестирование верстки ;)
            Вы проверяете соответствие макету.
            А тестировать, в моем понимании, проверять работу интерфейса на разных браузерах, в разных разрешениях и на разных операционных системах…
            Это один момент.

            Есть — второй момент, это уже больше касается юзабилити.
            Я например для этого использую яндекс.метрику и его инструмент — Вебвизор.
            С его помощью, я смотрю поведение пользователя на сайте — куда он курсор наводит, куда кликает, что копирует и прочие действия…
            В итоге, те элементы (кнопки, менюшки) что наиболее часто используемые — я их размещаю на самом удобном для пользователе плане. А что мало используется — убираю или скрываю под дополнительные опции…
            Это офигенно, особенно под адаптивный дизайн, под мобильные. Кучу коррекций выявил только по одному этому Вебвизору.
            • 0
              Тут есть элементы именно того тестирования, о котором вы говорите. Поскольку Мейкап — веб-приложение, его можно открывать в разных браузерах и на разных ОС. Разница в том, что можно не приводить большое и сложное приложение в определенное состояние, которое вы хотите проверить, а сразу отрендерить блок в нужном состоянии. Соответственно, задача регрессии вёрстки блока — просто прокликать все готовые, заранее сохраненные кейсы.
              • 0
                А как будете тестировать работу скриптов?
                Допустим пользователь произвел действие, а например AngularJS «перерисовал» интерфейс.
                Как узнаем, что действие вышло успешным и ничего не слетело (допустим, тег забыли по коду закрыть)?
                • 0
                  Скрипты мы тестируем другими инструментами. Например, линтерами и юнит-тестами.
              • 0
                Второй момент, о котором вы говорите, не имеет ничего общего с версткой. Это часть UX, отделяющаяся постепенно в отдельное направление под названием CX (Client Experience)
                • 0
                  Это бюджетный вариант тестирования интерфейса на фокусной группе :)
                  Косяки в верстке тоже всплывают.
                  Например, включаешь плей сессии и видишь, что клиент зашел с телефона с разрешением 320. И вот при таком разрешении появляется на одной из топовых страниц горизонтальный скролл — на странице одно из слов в заголовке не умещается, вот и распирает страницу. Тогда берем и правим цсс для таких экранов, делаем шрифт чуть меньше.

                  • 0
                    В данном случае верстка — это лишь инструмент. Как и дизайн. Но сам процесс, о котором вы говорите — это именно CX. Увеличение конверсии по результатам тестирования в реальных условиях. Тут и косяки верстки выявляются, и дизайна как такового, и текстов. Все вместе. Я просто говорю о более глобальном процессе. =)
              • +3
                Очень клевый подход, молодцы!

                Скажите пожалуйста, планируется ли адаптация этого инструмента для react?
                • +2
                  В репозитории есть ветка, в которой есть кое-какие эксперименты на эту тему. В будущем очень хочется довести эти эксперименты до релиза. =)
                  • 0
                    Есть нечто подобное для реакта пока еще нестабильное https://github.com/scup/atellier
                  • +1
                    А будет/планируется ли интеграция Makeup в TARS?
                    • +1
                      Задача пока в backlog'е. Думаю весной вернемся к ней. Следить можно за этим issue.
                    • 0
                      Я не очень поменял, как вы описываете состояние каждого блока. Можно примерчик?

                      Офф: отсюда — сюда. Это фейл по-моему
                      • 0
                        Для https://2gis.ru, например, используются свой javascript-фреймворк Slot. В нем шаблоны рендерятся с помощью handlebars.

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

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

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

                        Для других фреймворков система аналогичная. Для React, к примеру, это может быть props для компонента.
                        • 0
                          Ну т.е. ваш инструмент может взять допустим реактовский или ангуларовский компонент. И отрендерить в нескольких состояниях. Верно?
                          • 0
                            Да, но способ, как именно рендерить компоненты, нужно будет указать Мейкапу отдельно.
                      • 0
                        Есть пересекающаяся тема по автоматизации тестирования верстки: — visual diffing tools: webdiff, dpxdt, etc.
                        https://www.youtube.com/watch?v=jUUTqgzNR3M с конференции по Пайтон 2015 и слайды http://bit.ly/pycon2015-visual-diffs
                        • +1
                          Говоря об инструментах, которые решают похожую задачу, стоит упомянуть еще о Gemini и Galen Framework.
                        • 0
                          Не совсем понял, решает ли ваш инструмент проблему кроссбраузерности верстки? То есть в Chrome может работать все ок, а в Android браузере верстка ломается, через что вы прогоняете ваши тесты?
                          • 0
                            Мейкап нельзя назвать средством автоматизации. Это инструмент, в котором можно посмотреть набор заранее сохраненных кейсов данных для блока.

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

                            Для мобильных браузеров это возможно, но не так удобно, как в случае с большими экранами.
                          • 0
                            Очень интересный проект, я для таких целей в хроме использовал PixelPerfect, но есть всегда одна проблема, если я все правильно понял, то для работы например в различных состояниях нужно иметь несколько скриншотов этого состояния, пример: различные размеры экрана., различные ОС.
                            Если со вторым еще можно справиться, то как быть с первым?
                            А вообще задумка чертовски хороша, но 16 февраля Яндекс проводили свою школу дизайна и там Антоном Шеиным, была замечена очень хорошая вещь для дизайнеров — научитесь уже наконец таки использовать веб-технологии и будет вам радость.
                            В этом случае и дизайнер и разработчик будут говорить на одном языке.

                            Но повторюсь, Ваш подход несколько интересный и вообщем жду его дальнейшего развития.
                            • 0
                              Спасибо за высокую оценку.

                              Мы иногда практикуем состояния без приложенных скриншотов. Тогда можно просто посмотреть глазами, нормально ли выглядит блок. Есть и второй способ: можно не сохранять отдельное состояние, а в каком-то другом подергать ползунок и поменять ширину.
                              • 0
                                Просто например на данный момент, я много работаю с мобильной версткой в приложении и вот тут назревает вопрос, как тестировать такую верстку?
                                Если например с iOS все ясно и понятно, то с Android есть проблемы, слишком большое кол-во размеров у экранов.
                                Конечно же надо делать ее резиновой, но что делать если надо вставить в background картинку, на одном из экранов она так или иначе возьмет либо растянется, либо еще чего. Но я ушел от сути…
                                Я думаю вы доработаете и будет неплохой инструмент для верстальщиков!
                            • 0
                              А вы пробовали gemini: https://github.com/gemini-testing/gemini?
                              Тем более что вы используете БЭМ.
                              • 0
                                Gemini — обеспечивает визуальную регрессию в сравнении с предыдущими итерациями. Нам важно было иметь представление, насколько верстка соответствует первоначальному дизайну. А сравнивать с макетами автоматически почти невозможно: радикально будут отличаться рендеринг шрифтов, например.

                                А вообще, Gemini — отличный инструмент. Реконмендовал его в этом комментарии.

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое