Screenshot Driven Development: автоматизация тестирования путем снятия скриншотов Тестирование
Тезисы
Любая компания, разрабатывающая современное кросс-платформенное приложение (как нативное, так и веб), сталкивается с рядом проблем:
1) Фрагментация (огромное количество типов и версий устройств, операционных систем, браузеров, представлений, поддерживаемых языков).
2) Регрессия (мелкое исправление в UI приводит к проблемам на других ОС, браузерах и состояниях).
3) Контролируемость изменений (со временем становится все сложнее ревьюить изменения кода в UI).
В настоящее время существует ряд инструментариев, помогающих решить данные проблемы:
1) Средства автоматизации тестирования UI для нативных приложений (например, Sikuli). Основные недостатки данных решений – это работа с приложением внешним образом (как «black box») и неустойчивость к изменениям (при модификации UI приложения приходится переделывать большинство написанных автотестов).
2) Библиотеки для Web, позволяющие снимать и сравнивать скриншоты HTML-страниц: PhantomCSS, Kaidan, Wraith. Обычно используют один браузер в качестве движка рендеринга (чаще всего PhantomJS), таким образом не решают проблему фрагментации, однако позволяют контролировать изменения кода и обнаруживать регрессионные проблемы. Также к плюсам можно отнести возможность запуска локально, без зависимости на внешние сервисы/инфраструктуру (тем самым достаточно несложно включить такие инструменты в Continuous Integration компании, однако не без дополнительных доработок).
3) Облачные сервисы (BrowserStack.com, CrossBrowserTesting.com, SauceLabs.com). К достоинствам такого инструментария, без сомнения, стоит отнести большое количество поддерживаемых браузеров и платформ (включая мобильные), однако облачный характер сервисов создает ряд ограничений, таких как необходимость работы online и внешнего доступа к ресурсу, который требуется протестировать.
Наша компания разрабатывает как нативные, так и веб-приложения под разные платформы, и описанные выше проблемы стали для нас актуальны еще несколько лет назад. Они заставили заняться созданием инструментария, позволяющего контролировать процесс работы над UI в наших проектах. В итоге мы пришли к следующему подходу:
1) Разработчик помимо кода описывает набор различных состояний (представлений) приложения/страницы/элемента, которые считает целесообразным покрыть скриншотами. В этом подход очень похож на unit-тесты, в которых в каждом тесте система вводится в нужное состояние, однако без описания assert’ов: вместо этого приложение будет «заскриншочено» в каждом описанном состоянии на каждом поддерживаемом устройстве, операционной системе, браузере, разрешении, языке.
2) Процедура снятия скриншотов включена в общую инфраструктуру Continuous Integration в нашей компании: прогоны осуществляются каждую ночь, по результатам этих прогонов рассылаются письма с отчетом о различиях по отношению к предыдущему прогону.
3) «Незначительные» различия (сглаживания шрифтов, визуальные эффекты) игнорируются, в отчетах по различиям показывается что-то наподобие «тепловой карты» изменений, где красным показаны важные различия, а желтым – незначительные. Скриншоты, содержащие только незначительные изменения (или не имеющие их вовсе) не включаются в отчет.
4) Удобная визуализация изменений позволяет просматривать такие отчеты, не тратя много времени и быстро отличая «правильные» изменения от «неправильных» (добавление нового элемента или смена компоновки страницы – это «правильное» изменение, вызванное модификацией приложения, а «поехавшая» в Safari верстка в связи с исправлениями под IE8 – это изменение «неправильное»).
Немного про реализацию. Инструментарий включает себя реализацию на C++ (Qt + QtWebKit), Python, JavaScript, для взаимодействия с браузерами используются Selenium Web Drivers, запуск различных версий браузеров осуществляется в виртуальных машинах через VirtualBox API, для снятия скриншотов на мобильных платформах используются iOS/Android-эмуляторы. Скриншоты снимаются в 11 различных браузерах (IE8+, Firefox, Chrome, Opera, Safari, Android Browser, Mobile Chrome, Safari Mobile), 6 различных типах DPI, 6 версиях операционных систем, нескольких языках. На текущий момент всего снято 2000000+ скриншотов (224 ГБ).