Визуальное регрессионное тестирование за последние несколько лет стало дополнительной подушкой комфорта при тестировании того, что сайт работает правильно в отношении пользовательского интерфейса.

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

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

Скелет тестирования

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

После первоначальной настройки у нас был фундамент, на который можно было опереться. BackstopJS настраивается с помощью файла backstop.json, созданного во время установки. Этот файл конфигурации может быть основан на JS, если это предпочтительнее, с учетом переменных, логики и комментариев, что дает 1-2-3 удара по тонкостям разработчика. Мы выбрали этот вариант, чтобы обеспечить дополнительную гибкость и сделать нашу конфигурацию более СУХОЙ.

Еще раз с чувством

В недавно переименованном и слегка реструктурированном файле backstop.js выполняются все настройки для визуального тестирования с использованием BackstopJS. Базовый файл конфигурации JS теперь выглядит примерно так (или вы можете увидеть конфиг BackstopJS по умолчанию)

module.exports = { id: 'ID', viewports: [ ..viewportsArray.. ], scenarios: [ { label: 'Components', url: 'http://foo.bar/baz', selectors: [ '.foo' ], selectorExpansion: true, hideSelectors: [], removeSelectors: [], readyEvent: null, delay: 500, misMatchThreshold : 0.1, onReadyScript: 'onReady.js' } ], paths: { ..pathsObject.. }, casperFlags: [], engine: 'phantomjs', report: ['cli'], debug: false }

В частях viewports и scenarios происходит волшебство. scenarios сообщает BackstopJS, что и как делать скриншоты, а viewports объясняет, при каких размерах экрана следует делать эти скриншоты.

Где это вписывается в рабочий процесс

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

Сам модуль также основан на Promise и вписывается в рабочий процесс gulp, как самостоятельная задача, как перчатка. Мы устанавливаем объект конфигурации для передачи в резервную копию вместе с определением двух отдельных задач — одной для создания эталонных снимков и одной для запуска тестов с использованием этого.

//Config object var backstopConfig = { //Config file location config: '/path/to/file.js' //incremental reference image capturing i: true } //Generate Reference files gulp.task('visual-test:reference', function() { return backstopjs('reference', backstopConfig); }); //Generate Test files and compare with reference gulp.task('visual-test:test', function(done) { return backstopjs('test', backstopConfig); });

Упрощаем себе жизнь

Базовая установка для выполнения тестов состоит в том, чтобы запустить тест слева направо (в данном случае на английской странице) и точно такой же тест, как и тест справа налево (арабская страница). Это будет означать, что любое количество имеющихся у вас тестовых сценариев будет удвоено из-за требований к тестам ltr и rtl. Окна просмотра и селекторы для этих вариантов LTR и RTL в нашем случае будут одинаковыми. Имея это в виду, селекторы сценариев были разделены на отдельный файл для конфигурации.

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

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

Объединяя все это

С учетом аспектов, упомянутых ранее, и нескольких других рефакторингов окончательный файл конфигурации выглядел так.

Некоторые области здесь были расширены и обновлены. Был введен модуль yargs, позволяющий использовать аргументы командной строки для повышения гибкости при запуске Backstop, в основном задавая ключ конфигурации debug и базовый URL-адрес для тестирования.

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

При необходимости могут быть выполнены и другие области рефакторинга, такие как сами сценарии.

//parse command line arguments var argv = require('yargs').argv; //Get the base URL from command line argument. If that isn't provided, use the default var BASE_URL = (typeof argv.url === 'undefined') ? 'http://default-test-url.foo/' : argv.url; //Get debug value from command line argument. // If not provided returns 'undefined' - 'double bang' coerces the value to a boolean var DEBUG = !!argv.debug; //Set how much is considered to be a valid percentage mismatch. // - Anything lower is a pass, // - Anything higher is a fail, var MISMATCH_PERCENTAGE_THRESHOLD = 4; //Test viewports var viewports = require('./config/viewports.js'); //component selector list var components = require('./config/components'); //BackstopJS paths var paths = require('./config/paths'); //Helper function to create full URL string function getFullUrl(pageUrl) { return BASE_URL + pageUrl; } module.exports = { id: 'AI', viewports: viewports, scenarios: [ { label: 'Components EN', url: getFullUrl('en/awesome-page'), selectors: components.static, selectorExpansion: true, hideSelectors: components.hide, removeSelectors: [], readyEvent: null, delay: 1000, misMatchThreshold : MISMATCH_PERCENTAGE_THRESHOLD, onReadyScript: 'onReady.js' }, { label: 'Components AR', url: getFullUrl('ar/awesome-page'), selectors: components.static, selectorExpansion: true, hideSelectors: components.hide, removeSelectors: [], readyEvent: null, delay: 1000, misMatchThreshold : MISMATCH_PERCENTAGE_THRESHOLD, onReadyScript: 'onReady.js' } ], paths: paths, casperFlags: [], report: ['cli', 'CI'], ci: { format: 'junit', testSuiteName: 'backstopJS' }, debug: DEBUG }

Пример использования:

# run the reference task using the provided url gulp visual-test:reference --url=http://custom-domain.dev # run the test task with debug logging turned on gulp visual-test:test --debug

это обертка

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

Реализация этого показала, что на странице руководства по стилю, которую мы тестируем, отсутствуют несколько компонентов. Их отсутствие выявляет пробелы в тестовом покрытии. Следующей задачей будет полное обновление руководства по стилю!

Тестируемый сайт также использует ленивую загрузку для многих изображений. На момент написания они не учитывались тестами — вместо этого они отображались серым блоком. Хотя это и относится к тестированию самого контента, оно не полностью отражает реалистичный взгляд на компоненты. Если все изображения прерываются, показывая серый фон, тесты могут дать ложноположительный результат и быть пройдены.

Первоначально опубликовано на сайте lean.codecomputerlove.com 6 февраля 2017 г.