Написано по просьбам из соседнего топика — Как мы тестируем поиск в Яндексе. Screenshot-based тестирование блоков результатов
История про глубокий рефакторинг.
В нашем приложении был один модуль, реализованный на заре бизнеса. Модуль был реализован используя отличные от других модулей патерны, во всю эксплуатировал глобальные переменные, состоял из более чем сотни javascript файлов, которые были тесно связаны друг с другом. Малоизвестный фреймворк, на базе которого был сделан модуль, больше не использовался нигде. В результате, исправление ошибок или добавление новой функциональности занимало у команды в 2-3 раза больше времени, по сравнению с другими модулями. В связи с грядущими изменениями функциональности назрела острая необходимость отрефакторить этот немаленький модуль.
Юнит тестирование в данном случае не подходило, т.к. модуль менялся чуть меньше чем полностью. Чтобы автоматизировать функциональное тестирование модуля был выбран phantomjs
Важное значение в работе приложения имеет визуальная составляющая — подсветка всяческих элементов, правильное расположение на странице, корректное отображение данных. Чтобы отслеживать визуальные изменения было решено во время тестов делать скриншоты. Благо phantomjs позволяет это легко делать:
page.render('test0001-after-login.png');
Было написано достаточное количество тестов, охватывающих функциональность в известном нам объеме. Как выяснилось позже, знали мы недостаточно глубоко :) Эти тесты генерировали несколько сотен скриншотов. Очевидно, что сравнивать картинки между собой — занятие совершенно неблагодарное. Нужно делать это автоматически. В одном из предыдущих проектов я реализовал на Питоне некоторое количество скриптов манипулирующими картинками (резать, клеить, находить регионы, накладывать картинки друг на друга и пр) и был готов зарядить его и для этой задачи.
Обошлось всё без изобретения велосипедов. Была задействован мощный кроссплатформенный пакет утилит — ImageMagick
compare может сравнить два скриншота, подсветить разницу и вывести информацию на экран.
Пример вызова:
compare.exe -metric AE shots/test-002_opentree.png reference/test-002_opentree.png diff-002.png 2>&1
Берем свежий скриншот, сравниваем с референсным, выводим текстовую информацию на экран, а графическую сохраняем в файл для ручного просмотра подробностей.
Трудно заметить разницу между этими двумя скриншотами:
Но когда разница подсвечена, то всё достаточно очевидно — у одного блока сплошная граница, а не точечная:
Первые две картинки сделаны тестом phatomjs, а последняя — результат работы compare. Часть информации заблюрена, т.к. у меня нет официального разрешения на публикацию интерфейса нашей программы, хотя бы и устаревшего.
Окончательный мазок пера — скрипт на poweshell, который сравнивает папку со свежими скриншотами и папку с референсными картинками, а после сравнения убивает те, что не представляют интереса. Скрипт легко может быть переделан на более платформо независмый язык.
Не забудьте заглянуть в скрипт перед запуском его из командной строки. Винды по умолчанию не разрешают запуск неподписанных скриптов. Что с этим делать написано в шапке.
Скрипт лежит тут — detectChanges.ps1
ЗЫ. приношу извинения за дезинформацию насчет использования Питона для решения этой задачи.
Автор: TedBeer