Тестирование расширений браузера

Я собираюсь написать кучу расширений браузера (такая же функциональность для каждого популярного браузера). Надеюсь, что часть кода будет разделена, но я пока не уверен в этом. Конечно, некоторые расширения будут использовать собственный API. У меня мало опыта с TDD/BDD, и я подумал, что пришло время начать с этих идей из этого проекта.

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

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

Ответ 1

Я практикую два разных способа тестирования расширений моего браузера:

  • Модульные тесты
  • Интеграционный тест

Введение

В качестве примера в этом ответе я буду использовать расширенный браузер YouTube Lyrics от Rob W. Ядро этого расширения написано на JavaScript и организовано с использованием модулей AMD. Конструкция script создает файлы расширений для каждого браузера. С r.js я оптимизирую включение модулей, специфичных для браузера, таких как HTTP-запросы с кросс-началом и постоянное хранилище (для предпочтений ) и модуль с множеством полиполнений для IE.

Расширение вставляет панель с текстом для текущей песни на YouTube, Grooveshark и Spotify. Я не контролирую эти сторонние сайты, поэтому мне нужен автоматический способ проверить, что расширение все еще работает хорошо.

Workflow

В процессе разработки:

  • Внедрить/отредактировать функцию и написать unit test, если эта функция не является тривиальной.
  • Запустите все модульные тесты, чтобы увидеть, что-то сломалось. Если что-то не так, вернитесь к 1.
  • Обязательно git.

Перед выпуском:

  • Запустите все модульные тесты, чтобы убедиться, что отдельные модули все еще работают.
  • Запустите все тесты интеграции, чтобы убедиться, что расширение в целом все еще работает.
  • Версии Bump, расширения для сборки.
  • Загрузите обновления в официальные галереи расширений и мой сайт (Safari и расширения IE должны быть размещены сами) и зафиксируйте git.

Единичное тестирование

Я использую mocha + expect.js написать тесты. Я не тестирую каждый метод для каждого модуля, только те, которые имеют значение. Например:

  • Метод разбора DOM. Большинство методов разбора DOM в дикой природе (включая jQuery) ошибочны: любые внешние ресурсы загружаются и выполняется JavaScript.
    Я проверяю, что метод разбора DOM правильно анализирует DOM без отрицательных побочных эффектов.

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

  • Мое расширение извлекает текст из внешних источников. Эти источники определены в отдельных модулях. Эти определения распознаются и используются модулем InfoProvider, который берет запрос (черный ящик) и выводит результаты поиска.

    • Сначала я проверяю, правильно ли функционирует модуль InfoProvider.
    • Затем для каждого из 17 источников я передаю предварительно определенный запрос источнику (с InfoProvider) и проверяю, ожидаются ли результаты:
      • Запрос успешно
      • Возвращаемое название песни соответствует (применяет алгоритм сходства слов)
      • Длина возвращаемых текстов попадает в ожидаемый диапазон.
  • Не нарушен ли пользовательский интерфейс, например. нажав кнопку "Закрыть".

Эти тесты можно запускать непосредственно с локального сервера или в пределах расширения браузера. Преимущество локального сервера заключается в том, что вы можете отредактировать тест и обновить браузер, чтобы увидеть результаты. Если все эти тесты проходят, я запускаю тесты из расширения браузера.
Передав дополнительный параметр debug в мою сборку script, модульные тесты связаны с моим расширением.

Выполнение тестов внутри веб-страницы недостаточно, поскольку среда расширения может отличаться от обычной страницы. Например, в расширении Opera 12 нет глобального объекта location.

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

Резюме

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

Тестирование интеграции

Я использую Selenium 2 для проверки того, работает ли мое расширение на YouTube, Grooveshark (3x) и Spotify.

Вначале я использовал Selenium IDE для записи тестов и выяснения, работает ли он. Все прошло хорошо, пока мне не потребовалось больше гибкости: я хотел условно запустить тест в зависимости от того, была ли зарегистрирована тестовая учетная запись или нет. Это невозможно при использовании Selenium IDE по умолчанию (возможно, это возможно с плагин FlowControl - я не пробовал).

Selenium IDE предлагает возможность экспортировать существующие тесты в других форматах, включая тесты JUnit 4 (Java). К сожалению, этот результат не был удовлетворительным. Многие команды не были распознаны.

Итак, я отказался от Selenium IDE и переключился на Selenium.
Обратите внимание, что при поиске "Selenium" вы найдете информацию о Selenium RC (Selenium 1) и Selenium WebDriver (Selenium 2). Первый - старый и устаревший, последний (Selenium WebDriver) должен использоваться для новых проектов.

Как только вы узнали, как работает документация, он довольно прост в использовании.
Я предпочитаю документацию на странице проекта, потому что она в целом краткая (wiki) и завершает (Java docs).

Если вы хотите быстро начать работу, прочитайте страницу Getting Started wiki. Если у вас есть свободное время, просмотрите документацию в SeleniumHQ, в частности Selenium WebDriver и WebDriver: расширенное использование.
Селеновая сетка также стоит прочитать. Эта функция позволяет распространять тесты на разных (виртуальных) машинах. Отлично, если вы хотите протестировать расширение в IE8, 9 и 10 одновременно (для запуска нескольких версий Internet Explorer вам потребуется виртуализация).

Автоматизация тестов хороша. Что еще приятно? Автоматическая установка расширений!
ChromeDriver и FirefoxDriver поддерживают установку расширений, как показано в этом примере.

Для SafariDriver я написал два класса для установки пользовательского расширения Safari. Я опубликовал его и отправил в PR для Selenium, поэтому он может быть доступен для всех в будущем: https://github.com/SeleniumHQ/selenium/pull/87

OperaDriver не поддерживает установку пользовательских расширений (технически это должно быть возможно).
Обратите внимание, что с появлением Chromium-powered Opera старый OperaDriver больше не работает.

Там есть драйвер Internet Explorer, и это, безусловно, не позволяет устанавливать пользовательское расширение. Internet Explorer не имеет встроенной поддержки расширений. Расширения устанавливаются через установщики MSI или EXE, которые даже не интегрированы в Internet Explorer. Итак, чтобы автоматически установить расширение в IE, вы должны иметь возможность тихо запускать установщик, который устанавливает ваш IE-плагин. Я еще не пробовал.

Ответ 2

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

Я использую следующие шаги:

Во-первых, я пишу тестовый код, интегрированный в код расширения, который можно активировать, просто перейдя к определенному URL-адресу. Когда расширение видит этот URL-адрес, он начинает выполнение тестов.

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

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

http://docs.seleniumhq.org/

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

Как правило, для разработки расширений кросс-браузера для поддержки единой базы кода я использую crossrider, но вы можете сделать это с любой структурой или с родными расширениями, как вы пожелаете, Selenium все равно, он просто управляет расширения на конкретную страницу и позволяет вам взаимодействовать и выполнять тесты.

Одна хорошая вещь об этом подходе - вы можете использовать его и для живых пользователей. Если вы предоставляете поддержку своего расширения, попросите пользователя перейти к вашему тестовому URL-адресу, и вы сразу увидите производительность внутреннего и внешнего сервера. Разумеется, вы не получите тесты Selenium, но вы поймете много проблем таким образом - очень полезно, когда вы кодируете множество браузеров и версии браузера.