Сколько отличий вы найдете за 10 секунд?
Наш тестировщик найдет ВСЕ отличия. И даже те, которые не видны. Ниже я расскажу о том, как он это сделает, но для начала немного введу вас в курс дела.
В нашей компании ведется разработка разных веб-приложений. Возьмем для примера типичное клиентское веб-приложение с богатым UI, несколькими сотнями страниц, адаптивной версткой и поддержкой всех популярных браузеров. При таком раскладе регрессионное тестирование существующего UI превращается в АД и отнимает кучу времени. Чтобы не сойти с ума и не погрязнуть в этой трясине, мы автоматизировали этот процесс и создали новый инструмент — QVisual.
Как человек тестирует верстку (UI)? Он берет текущую реализацию и сравнивает ее с абстрактным эталоном, построенным на базе собственного опыта, удобства и тысячи просмотренных до этого веб-страниц. Написать свой ИИ для тестирования верстки было бы, конечно, очень круто. Но эта идея выглядит стрельбой из пушки по воробьям. Поэтому мы поступили проще: в качестве эталона мы стали принимать такую же страницу, предварительно проверенную человеком (в большинстве случаев это страница из прошлого успешного релиза). Таким образом, вся задача свелась к сравнению двух страниц.
Безусловно, уже опубликовано много решений, которые позволяют попиксельно сравнивать две картинки. Зачем же мы написали «очередной велосипед»? Ответ прост — мы не хотели ограничиваться попиксельным сравнением, хотели иметь возможность сопоставлять отдельные блоки на странице и получать осмысленный отчет о количестве и типах различий в этих блоках. Поэтому реализованный нами инструмент может сравнивать не только сами картинки, но и отдельные элементы страницы, если это требуется. Так мы оперируем не скриншотами с двух страниц, а снэпшотами этих страниц.
Снэпшот – это скриншот всей страницы плюс данные о стилях и свойствах некоторых веб-элементов данной страницы. Поиск различий в снэпшотах мы реализуем серверным приложением с открытым API.
Подход: сравнение элементов, а не картинок позволяет нам выделить типовые ошибки, такие как:
Небольшой разбор примеров с рядом типовых ошибок:
Снять снэпшот со страницы можно при помощи собственных инструментов, а передать на сервер скриншот и данные об элементах можно двумя обычным POST-запросами.
Если ваши тесты написаны на Java, то проще будет воспользоваться для этих целей нашей библиотекой, которая сама позаботится о создании снэпшота и передаче данных на сервер.
Перед началом работы потребуется указать несколько переменных (адрес сервера, тип и версия браузера и т.д.). В самом тесте необходимо указать адрес страницы, с которой нужно снять снэпшот, и список локаторов в формате Xpath или CSS для поиска нужных нам элементов (опционально). That's all!
Внутри библиотеки для снятия снэпшота мы пользуемся внутренними командами Selenium WebDriver’a и скриптами на JavaScript. Внутренние команды WebDriver’a позволяют быстро и качественно сделать скриншоты страницы (без склеек и скролов), а js – найти нужные элементы и добавить данные о них в снэпшот. После снятия снэпшота передаем его нашему серверному приложению, которое сохранит данные об элементах в mongo, а сами скриншоты на диске сервера. Теперь этот снэпшот можно сопоставить с эталоном. Данные элементов будут сравниваться, как обычные объекты, а скриншоты – попиксельно с помощью OpenCV.
Теперь можно получить отчет о сравнении двух снэпшотов. Для этого нужно отправить GET-запрос и получить в ответ данные о сравнении в виде JSON, либо воспользоваться нашим фронтовым приложением, которое построит детальный, а самое главное удобночитаемый отчет.
Главная страница отчета содержит информацию об успешно пройденных и проваленных тестах (выделены красным цветом) и состоит из трех списков:
В верхней части расположены иконки, которые позволяют отфильтровать результаты в зависимости от типа ошибок и процентного расхождения в попиксельном сравнении. Данная реализация ускоряет верификацию ошибок.
Краткая статистика в блоках последнего списка содержит три параметра:
Отчет по каждой странице представляет собой два отдельных скриншота и обводки элементов, в которых были найдены diff. Всплывающий текст при наведении на отличающиеся элементы указывает на тип ошибки и локатор, по которому был найден элемент. Также можно выставить фильтрацию по типу ошибок, скрыть один из скриншотов и включить/отключить результат попиксельного сравнения.
Как уже было сказано выше, мы также сравниваем скриншоты попиксельно, что для некоторых задач весьма эффективно. Например, для новых страниц, с еще неустоявшейся DOM, нет смысла тратить время на написание и поддержку локаторов.
В завершение хочется сказать о реальном выхлопе данного инструмента для компании: изо дня в день QVisual помогает нашим тестировщикам быть в курсе всех изменений верстки приложений. Мы экономим массу времени на сравнении лэндингов с помощью автоматического создания скриншотов (до 1500+ лэндингов в 3х браузерах в 6 разрешениях экранов).
P.S.Это краткий обзор нашего инструмента. Более подробную информацию вы можете найти на GitHub, а также поучаствовать в развитии инструмента.
P.P.S. Для желающих проверить себя — вот все отличия в картинке из заголовка:
Наш тестировщик найдет ВСЕ отличия. И даже те, которые не видны. Ниже я расскажу о том, как он это сделает, но для начала немного введу вас в курс дела.
В нашей компании ведется разработка разных веб-приложений. Возьмем для примера типичное клиентское веб-приложение с богатым UI, несколькими сотнями страниц, адаптивной версткой и поддержкой всех популярных браузеров. При таком раскладе регрессионное тестирование существующего UI превращается в АД и отнимает кучу времени. Чтобы не сойти с ума и не погрязнуть в этой трясине, мы автоматизировали этот процесс и создали новый инструмент — QVisual.
Как человек тестирует верстку (UI)? Он берет текущую реализацию и сравнивает ее с абстрактным эталоном, построенным на базе собственного опыта, удобства и тысячи просмотренных до этого веб-страниц. Написать свой ИИ для тестирования верстки было бы, конечно, очень круто. Но эта идея выглядит стрельбой из пушки по воробьям. Поэтому мы поступили проще: в качестве эталона мы стали принимать такую же страницу, предварительно проверенную человеком (в большинстве случаев это страница из прошлого успешного релиза). Таким образом, вся задача свелась к сравнению двух страниц.
Безусловно, уже опубликовано много решений, которые позволяют попиксельно сравнивать две картинки. Зачем же мы написали «очередной велосипед»? Ответ прост — мы не хотели ограничиваться попиксельным сравнением, хотели иметь возможность сопоставлять отдельные блоки на странице и получать осмысленный отчет о количестве и типах различий в этих блоках. Поэтому реализованный нами инструмент может сравнивать не только сами картинки, но и отдельные элементы страницы, если это требуется. Так мы оперируем не скриншотами с двух страниц, а снэпшотами этих страниц.
Преимущества подхода
Снэпшот – это скриншот всей страницы плюс данные о стилях и свойствах некоторых веб-элементов данной страницы. Поиск различий в снэпшотах мы реализуем серверным приложением с открытым API.
Подход: сравнение элементов, а не картинок позволяет нам выделить типовые ошибки, такие как:
- IMAGE – элемент на странице визуально не соответствует элементу на эталоне;
- MOVED – смещение элементов, элемент идентичен эталонному, но с другими координатами;
- RESIZED – очень похоже на смещение, но вместо положения элемента отличается его размер;
- TEXT – ошибки в тексте;
- CSS и ATTRIBUTES – различия в стилях и атрибутах не всегда визуально заметны и не всегда являются ошибкой. Но контролировать изменения в них довольно полезно, поскольку в ряде случаев это помогает найти связанные с ними ошибки.
Небольшой разбор примеров с рядом типовых ошибок:
Как это работает?
Снять снэпшот со страницы можно при помощи собственных инструментов, а передать на сервер скриншот и данные об элементах можно двумя обычным POST-запросами.
Если ваши тесты написаны на Java, то проще будет воспользоваться для этих целей нашей библиотекой, которая сама позаботится о создании снэпшота и передаче данных на сервер.
Перед началом работы потребуется указать несколько переменных (адрес сервера, тип и версия браузера и т.д.). В самом тесте необходимо указать адрес страницы, с которой нужно снять снэпшот, и список локаторов в формате Xpath или CSS для поиска нужных нам элементов (опционально). That's all!
Внутри библиотеки для снятия снэпшота мы пользуемся внутренними командами Selenium WebDriver’a и скриптами на JavaScript. Внутренние команды WebDriver’a позволяют быстро и качественно сделать скриншоты страницы (без склеек и скролов), а js – найти нужные элементы и добавить данные о них в снэпшот. После снятия снэпшота передаем его нашему серверному приложению, которое сохранит данные об элементах в mongo, а сами скриншоты на диске сервера. Теперь этот снэпшот можно сопоставить с эталоном. Данные элементов будут сравниваться, как обычные объекты, а скриншоты – попиксельно с помощью OpenCV.
Теперь можно получить отчет о сравнении двух снэпшотов. Для этого нужно отправить GET-запрос и получить в ответ данные о сравнении в виде JSON, либо воспользоваться нашим фронтовым приложением, которое построит детальный, а самое главное удобночитаемый отчет.
А что в отчете?
Главная страница отчета содержит информацию об успешно пройденных и проваленных тестах (выделены красным цветом) и состоит из трех списков:
- список тестов (story), в которых проверялась верстка. Здесь для удобства названия тестов соответствуют url страниц, с которых был снят снэпшот;
- список состояний (state) – каждая story может содержать несколько состояний, например, скриншот до заполнения формы и после. Каждый state может содержать несколько снэпшотов в разных разрешениях и версиях браузера;
- список с разными браузерами и разрешениями и краткая статистика.
В верхней части расположены иконки, которые позволяют отфильтровать результаты в зависимости от типа ошибок и процентного расхождения в попиксельном сравнении. Данная реализация ускоряет верификацию ошибок.
Краткая статистика в блоках последнего списка содержит три параметра:
- pixels – отличие между двумя картинками в процентах относительно размера всей страницы;
- elements – количество отличающихся элементов (из тех, что были найдены по локаторам, переданным в тесте);
- error – внутренние ошибки, возникшие при сравнении снэпшотов (например, не найдена одна из картинок для сравнения, или нет данных по снэпшотам).
Отчет по каждой странице представляет собой два отдельных скриншота и обводки элементов, в которых были найдены diff. Всплывающий текст при наведении на отличающиеся элементы указывает на тип ошибки и локатор, по которому был найден элемент. Также можно выставить фильтрацию по типу ошибок, скрыть один из скриншотов и включить/отключить результат попиксельного сравнения.
Как уже было сказано выше, мы также сравниваем скриншоты попиксельно, что для некоторых задач весьма эффективно. Например, для новых страниц, с еще неустоявшейся DOM, нет смысла тратить время на написание и поддержку локаторов.
В завершение хочется сказать о реальном выхлопе данного инструмента для компании: изо дня в день QVisual помогает нашим тестировщикам быть в курсе всех изменений верстки приложений. Мы экономим массу времени на сравнении лэндингов с помощью автоматического создания скриншотов (до 1500+ лэндингов в 3х браузерах в 6 разрешениях экранов).
P.S.Это краткий обзор нашего инструмента. Более подробную информацию вы можете найти на GitHub, а также поучаствовать в развитии инструмента.
P.P.S. Для желающих проверить себя — вот все отличия в картинке из заголовка:
hurtavy
Отличия в картинках ищутся быстро. Разными глазами сводишь их в одну, ну как с трёхмерными изображениями. Все отличия начинают мерцать
motpac
Блин!!! А с какого расстояния смотреть? Я умею смотреть 3D картинки, но здесь поймать нужный фокус не смог.
hurtavy
отодвигайся, пока не совместятся. У меня получилось на 40см от экрана
Squoworode
Проще не с расстояния смотреть, а себе на нос.
ZoomLS
Действительно, так тоже можно :) А ещё нашёл одно отличие, на краю тарелки, недалеко от ломтиков лимона — на одном изображении на одну чёрную точку больше.
hurtavy
с точками не понятно. Там — jpg
xorbot
Всегда таким образом нахожу все отличия в подобных задачках:)
BingoBongo
Обычно в подобных задачах вторую картинку поворачивают на небольшой угол
Agel_Nash
dmitryredkin
Ну не все.
Например, отличия в цвете на ролле справа я таким образом заметить не смог.
taliban
:-D вот это лайфхак, но даже так я не заметил разницы в правом нижнем углу. У кусочка ролла форма и очертания идентичные, отличается лишь цвет.
Fragster
Значит вы неправильно смотрите стереокартинки. При правильном рассмотрении надо смотреть ЗА неё, и тогда изображение не «свести» более, чем на расстояние между глазами. Ну и сами стереокартинки получаются инвертированными (если только специально под такой «альтернативный» способ не сделаны, впрочем, все картинки, между соответствующими точками которых расстояние больше условно среднего расстояния между глазами — такие). А неправильно — это смотреть в точку перед изображением и отодвигать само изображение, как вы и пишете
Jeka178RUS
Фотошоп, копия слоя, смешивание слоев: разница и все как на ладони
Там кстати будет видно еще одно отличие: белая точка на фоне, внизу под темным пятном.
ShockwaveNN
Не слишком ли жирно покупать лицензию фотошопа для таких целей?
Ну и очевидный ответ — а если таких скриншотов десятки тысяч?
tinkoff_qa Автор
Как уже вам ответили, предложенный вами подход разобьется о количество сравниваемых изображений. В среднем обычное наше приложение содержит 150 страниц, и проверяется в 6 разрешениях на 3 браузерах, итого: 2700. А есть и больше.
Суть нашего подхода в том, что человек нужен только для разбора упавших тестов (сравнений).
Белая точка действительно не попала в выделенную зону. Финальная картинка не была получена в результате сравнения нашим инструментом. Но смею заверить, наш инструмент нашел бы ее ;)
pokryshkin
Когда bugbounty сделаете? Давно ведь обещали.
twitter.com/tinkoff_bank/status/745894508039135232
Jeka178RUS
Видимо ошибок слишком много, я постоянно косяки всякие нахожу, мелочи конечно
pokryshkin
Багов не мало. Практически каждый месяц пишу в техподдержку Тинькофф-Бизнес очередной репорт.
Молодцы: правят довольно быстро.
P.S. Что-то типа багбаунти все же есть, один раз за более-менее серьезный баг в безопасности дали месяц бесплатного обслуживания (порядка 2т.р.). Мелочь, а приятно. Но давно пора сделать её публичной.
KevlarBeaver
Если мне не изменяет память, мы (уже не мы) делали попиксельное (и, вроде, не только) сравнение изображений в регрессионных тестах на проекте Artisteer лет эдак, чтобы не соврать, восемь-десять назад. Да, думаю, много кто делал. Но публичного проекта, заточенного под эти цели, я не видел. Ну, здорово, конечно, что могу сказать :)
Dimash2
Такой тяжкий труд, стоил ли он свечь на фоне простого extension Pixel Perfect
speker
А разве можно Pixel Perfect'ом автоматически 50 страниц проверить в трех разных разрешениях и разных браузерах?
tinkoff_qa Автор
Как уже отвечал выше идея была по-максимуму автоматизировать этот процесс.
pushthebutton
Этот процесс встроен в CI? Если да, то как обрабатывается случай, если изменение верстки плановое?
И еще — если на целевой странице есть анимация, то есть присутствуют несколько слайдов с картинками и текстами (кнопками, да с чем угодно), которые листаются каждые n-минут. Как проверять их?
tinkoff_qa Автор
Да, CI есть. Несколько путей решения:
1) в финальном отчете выставляем фильтры в соответствии с изменениями и принимаем эти риски (например обновили стили, поэтому в отчете убираем из фильтрации ошибки css)
2) Если изменения касаются конкретных элементов, то убираем из списка локаторов те, что ссылаются на измененный (что тоже несет некоторые риски)
Для подстраховки используем скриншот-тесты отдельных компонент в Storybook: верстка, как правило меняется не радикально, а лишь отдельные элементы (банеры, кнопки, и т.д.). В storybook компоненты вынесены на отдельные страницы. Так, что проверка изменений не занимает много времени даже при «ручном» тестировании, а проверка остальных компонент на отсутствие изменений уже с помощью Qvisual.
Анимацию и динамический контент (банеры с рандомными рекомендации продуктов, например) перед снятием снапшота удаляем со страницы при помощи js. Потом отдельно проверяем другими тестами (иногда руками).