Автоматизация тестирования UI
При автоматизации тестов взаимодействий UI Вы освобождаете критически настроенный штат и ресурсы для другой работы. Таким образом Вы максимизируете производительность, минимизируете процедурные ошибки и сокращаетесь, количество времени должно было разработать обновления продукта.
Можно использовать инструмент Автоматизации для автоматизации тестов пользовательского интерфейса в приложении для iOS через сценарии тестирования, которые Вы пишете. Эти сценарии, выполненные за пределами Вашего приложения и, моделируют взаимодействие с пользователем путем вызова Автоматизации UI API, интерфейс программирования JavaScript, указывающий действия, которые будут выполняться в приложении, когда это работает в средстве моделирования или на подключенном устройстве. Ваши сценарии тестирования возвращают информацию о журнале главному компьютеру о выполняемых действиях. Можно даже интегрировать инструмент Автоматизации с другими инструментами для выполнения сложных тестов, таких как разыскивание утечек памяти и изоляция причин проблем производительности.
В этой главе описываются, как Вы используете шаблон Automation в Инструментах для выполнения сценариев. Шаблон трассировки Автоматизации выполняет сценарий, моделирующий взаимодействие UI для приложения для iOS, запущенного от Инструментов. Это состоит из инструмента Автоматизации только.
Эта глава также объясняет, как интегрировать Ваши сценарии с интерфейсом программирования Автоматизации UI, чтобы проверить, что Ваше приложение может сделать следующее:
Получите доступ к его иерархии элемента UI
Добавьте гибкость синхронизации при наличии периодов тайм-аута
Зарегистрируйте и проверьте информацию, возвращенную Инструментами
Дескриптор предупреждает должным образом
Дескриптор изменяется в ориентации устройства корректно
Многозадачность дескриптора
Инструмент Автоматизации обеспечивает мощные функции, включая:
Редактирование сценария со встроенным редактором сценариев
Получение (записи) действий пользовательского интерфейса для использования в сценариях автоматизации
Выполнение сценария тестирования из проекта XCode
Мощные функции API, включая возможность моделировать изменение местоположения устройства и выполнить задачу от инструмента Автоматизации на узле
Поскольку Вы работаете через эту главу, ищете более подробную информацию о каждом классе в Автоматизации UI Ссылка JavaScript для iOS. Для обзора Автоматизации UI с JavaScript посмотрите JavaScript для Информации о версии Автоматизации. Для некоторых демонстрационных проектов автоматизации посмотрите JavaScript для Автоматизации Демонстрации WWDC 2014 года.
Запись, экспортируя и импортируя сценарии тестирования автоматизации
Просто записать Ваши собственные сценарии в Инструментах. Встроенный редактор сценариев в инструменте Автоматизации позволяет Вам создавать и редактировать новые сценарии тестирования в своем документе трассировки, а также импортировать существующие.
Создайте новый документ трассировки в Инструментах с помощью шаблона трассировки Автоматизации.
С инструментом Автоматизации, выбранным в области Instruments, нажмите кнопку Display Settings (середина) на боковой панели инспектора.
Нажмите Add> Create.
Дважды щелкните по New Script для изменения имени сценария.
В Панели навигации области Detail выберите Script для ввода кода для сценария.
Выберите цель для своего сценария.
Щелкните по кнопке воспроизведения у основания область Automation> Script Detail.
После создания сценария Вы захотите использовать его в течение разработки Вашего приложения. Вы делаете это путем сохранения сконфигурированного документа трассировки (который включает сценарий), и открытие его снова каждый раз, когда Вы хотите протестировать свое приложение. Или, можно экспортировать сценарий тестирования и импортировать его в новый документ трассировки при необходимости в нем.
Загрузка сохраненных сценариев тестирования автоматизации
Вы пишете свои тесты Автоматизации в JavaScript, пользуясь библиотекой UI Automation JavaScript для указания действий, которые должны быть выполнены в приложении, когда это работает. Можно создать столько сценариев, сколько Вы любите и включаете их в свой документ трассировки, но можно выполнить только один сценарий за один раз. API действительно, однако, предлагает a #import
директива, позволяющая Вам писать меньшие, допускающие повторное использование дискретные сценарии тестирования. Например, если Вы определяете обычно используемые функции в названном файле TestUtilities.js
, можно сделать те функции доступными для использования в сценарии тестирования включением в тот сценарий строка:
#import "<path-to-library-folder>/TestUtilities.js"
Изменения, которые Вы вносите с редактором сценариев, сохраняются, когда Вы сохраняете свой документ трассировки. Для сценариев, создаваемых в редакторе, изменения сохраняются как часть самого документа трассировки. Для сохранения тех изменений в файле, можно получить доступ на диске, необходимо экспортировать сценарий. Посмотрите Для экспорта сценария в файл на диске выше.
Запись ручных действий пользовательского интерфейса в сценарии автоматизации
Функция получения упрощает разработку сценариев, позволяя Вам записать действия, которые Вы выполняете на целевом устройстве на iOS или в Средстве моделирования iOS. Для использования этой функции создайте документ трассировки Автоматизации и затем получите действия, которые Вы выполняете на устройстве. Эти полученные действия включены в Ваш сценарий как выражения, которые можно отредактировать.
Создайте или откройте документ трассировки, содержащий инструмент Автоматизации.
Нажмите кнопку Display Settings на боковой панели инспектора, при необходимости, для отображения настроек дисплея Сценариев.
Выберите свой сценарий из списка.
Щелкните в области редактора сценариев для расположения курсора, где Вы хотите, чтобы полученные действия появились в сценарии.
Нажмите Кнопку записи под текстовым редактором.
Запуски целевого приложения и состояние сценария обновляются, чтобы указать, что получение происходит.
Выполните желаемые действия с устройством или в средстве моделирования.
Щелкните по Кнопке остановки под текстовым редактором, чтобы прекратить получать действия.
Инструмент Автоматизации генерирует выражения в Вашем сценарии для действий, которые Вы выполняете. Некоторые из этих выражений включают маркеры, содержащие альтернативный синтаксис для выражения. Для наблюдения альтернативного синтаксиса выберите стрелку справа от маркера. Чтобы выбрать в настоящее время выводимый на экран синтаксис для маркера и сгладить выражение, дважды щелкните по маркеру.
Для конфигурирования инструмента Автоматизации, чтобы автоматически запустить и остановить сценарий под управлением Инструментальной Кнопки записи на панели инструментов установите флажок «Run on Record».
Если Ваши сбои приложения или переходят к фону, Ваш сценарий блокируется, пока приложение не является frontmost снова, в котором времени сценарий продолжает работать.
Доступ и управление элементами UI
Основанный на доступности механизм, лежащий в основе функции UI Automation, представляет каждое управление в Вашем приложении как уникально идентифицируемый элемент. Для выполнения действия с элементом в приложении Вы явно идентифицируете тот элемент с точки зрения иерархии элемента приложения. Чтобы полностью понять этот раздел необходимо быть знакомы с информацией в Инструкциях по Интерфейсу пользователя iOS.
Для иллюстрирования иерархии элемента этот раздел обращается к приложению для iOS Рецептов, показанному на рисунке 11-1, который доступен как пример кода iPhoneCoreDataRecipes от iOS Центр Dev.
Доступность элемента UI
Каждый доступный элемент наследован от основного элемента, UIAElement
. Каждый элемент может содержать нуль или больше других элементов.
Как детализировано ниже, Ваш сценарий может получить доступ к отдельным элементам их позицией в иерархии элемента. Однако можно присвоить уникальное имя каждому элементу путем установки атрибута метки и проверки, что Доступность выбрана в Интерфейсном Разработчике для управления, представленного тем элементом, как показано на рисунке 11-2.
Автоматизация UI использует метку доступности (если это установлено) получить свойство имени для каждого элемента. Кроме очевидных преимуществ, с помощью таких имен может значительно упростить разработку и обслуживание сценариев тестирования.
Свойство имени является одним из четырех свойств этих элементов, которые могут быть очень полезными в Ваших сценариях тестирования.
имя. Полученный из метки доступности
значение. Текущая стоимость управления, например, текста в текстовом поле
элементы. Любые дочерние элементы, содержавшие в элементе тока, например, ячейках в табличном представлении
родитель. Элемент, содержащий элемент тока
Понимание иерархии элемента
Наверху элемента иерархия UIATarget
класс, представляющий высокоуровневые элементы пользовательского интерфейса системы под тестом (SUT) — т.е. устройство (или средство моделирования), а также iOS и Ваше приложение, работающее на том устройстве. В целях Вашего теста Ваше приложение является frontmost приложением (или целевое приложение), идентифицированный следующим образом:
UIATarget.localTarget().frontMostApp(); |
Для достижения окна приложения, главного окна приложения, Вы указали бы
UIATarget.localTarget().frontMostApp().mainWindow(); |
При запуске окно приложения Рецептов появляется как показано на рисунке 11-1.
В окне список рецепта представлен в отдельном представлении, в этом случае, табличном представлении, посмотрите рисунок 11-3.
Это - первое табличное представление в массиве приложения табличных представлений, таким образом, Вы указываете его использование как таковое нулевого индекса ([0]), следующим образом:
UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0]; |
В табличном представлении каждый рецепт представлен отличной отдельной ячейкой. Можно указать отдельные ячейки точно так же. Например, с помощью нулевого индекса ([0]), можно указать первую ячейку следующим образом:
UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[0]; |
Каждый из этих элементов отдельной ячейки разработан для содержания записи рецепта как пользовательского дочернего элемента. в этой первой ячейке запись для шоколадного пирога, к которому можно получить доступ по имени с этой строкой кода:
UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[0].elements()["Chocolate Cake"]; |
Отображение иерархии элемента
Можно использовать logElementTree
метод для любого элемента для перечисления всех его дочерних элементов. Следующий код иллюстрирует перечисление элементов для основного экрана (Recipes) (или режим) приложения Рецептов.
// List element hierarchy for the Recipes screen |
UIALogger.logStart("Logging element tree ..."); |
UIATarget.localTarget().logElementTree(); |
UIALogger.logPass(); |
Вывод команды получен в журнале, выведенном на экран инструментом Автоматизации, как на рисунке 11-4.
Отметьте добавление отступа каждой позиции элемента, указав что уровень элемента в иерархии. Эти уровни могут быть просмотрены концептуально, как на рисунке 11-5.
Несмотря на то, что экран не является технически iOS программируемая конструкция и явно не появляется в иерархии, это - полезное понятие в понимании той иерархии. Ответвление вкладки Unit Conversion в панели вкладок выводит на экран экран Unit Conversion (или режим), показанный на рисунке 11-6.
Следующий код касается вкладки Unit Conversion в панели вкладок для отображения связанного экрана и затем регистрирует иерархию элемента, связанную с ним:
// List element hierarchy for the Unit Conversion screen |
var target = UIATarget.localTarget(); |
var appWindow = target.frontMostApp().mainWindow(); |
var element = target; |
appWindow.tabBar().buttons()["Unit Conversion"].tap(); |
UIALogger.logStart("Logging element tree …"); |
element.logElementTree(); |
UIALogger.logPass(); |
Получающийся журнал показывает иерархию, которая будет как проиллюстрирована на рисунке 11-7. Так же, как с предыдущим примером, logElementTree
вызывается для цели, но результаты для текущего экрана — в этом случае, экрана Unit Conversion.
Упрощение навигации иерархии элемента
Предыдущий пример кода представляет использование переменных для представления частей иерархии элемента. Этот метод допускает короче, более простые команды в Ваших сценариях.
Используя переменные таким образом также допускает некоторую абстракцию, приводя к гибкости в использовании кода и повторном использовании. Следующий пример использует переменную (destinationScreen
) управлять изменением между двумя основными экранами (Рецепты и Преобразование Модуля) приложения Рецептов:
// Switch screen (mode) based on value of variable |
var target = UIATarget.localTarget(); |
var app = target.frontMostApp(); |
var tabBar = app.mainWindow().tabBar(); |
var destinationScreen = "Recipes"; |
if (tabBar.selectedButton().name() != destinationScreen) { |
tabBar.buttons()[destinationScreen].tap(); |
} |
С незначительными изменениями этот код мог работать, например, для панели вкладок с большим количеством вкладок или с вкладками различных имен.
Выполнение жестов пользовательского интерфейса
Как только Вы понимаете, как получить доступ к желаемому элементу, это относительно просто и прямо для управления тем элементом.
Автоматизация UI API обеспечивает методы для выполнения большинства пользовательских действий UIKit, включая мультисенсорные жесты. Для всесторонней подробной информации об этих методах посмотрите Автоматизацию UI Ссылка JavaScript для iOS.
Ответвление. Возможно, наиболее распространенный сенсорный жест является простым касанием. Реализация единственного касания с одним пальцем на известном элементе UI очень проста. Например, ответвление правильной кнопки, маркированной знаком «плюс» (+), в панели навигации приложения Рецептов, выводит на экран новый экран, используемый для добавления нового рецепта.
Эта команда - все, что это требуется, чтобы касаться той кнопки:
UIATarget.localTarget().frontMostApp().navigationBar().buttons()["Add"].tap(); |
Обратите внимание на то, что это использует имя, Добавляют для идентификации кнопки, предполагая, что метка доступности была установлена соответственно, как описано выше.
Конечно, более сложные жесты касания требуются, чтобы полностью тестировать любое сложное приложение. Можно указать любые стандартные жесты касания. Например, для ответвления один раз в произвольном расположении на экране просто необходимо обеспечить координаты экрана:
UIATarget.localTarget().tap({x:100, y:200}); |
Эта команда касается в указанных координатах x и y, независимо от того, что в том расположении на экране.
Более сложные касания также доступны. К двойному касанию то же расположение Вы могли использовать этот код:
UIATarget.localTarget().doubleTap({x:100, y:200}); |
И выполнять касание с двумя пальцами для тестирования увеличения и уменьшения масштаба, например, Вы могли использовать этот код:
UIATarget.localTarget().twoFingerTap({x:100, y:200}); |
Зажимание. Повышение, которое открытый жест обычно используется, чтобы увеличить или развернуть объект на экране и повышение близкий жест, используется для противоположного эффекта — чтобы уменьшить масштаб или уменьшить объект на экране. Вы указываете координаты для определения запуска повышения близкий жест или конец повышения открытый жест, сопровождаемый на многие секунды на время жеста. Параметр продолжительности позволяет Вам некоторую гибкость в указании скорости действия повышения.
UIATarget.localTarget().pinchOpenFromToForDuration({x:20, y:200}, {x:300, y:200}, 2); |
UIATarget.localTarget().pinchCloseFromToForDuration({x:20, y:200}, {x:300, y:200}, 2); |
Перетаскивание и щелкающий. Если необходимо просмотреть таблицу путем прокрутки или переместить элемент в экран, можно использовать dragFromToForDuration
метод. Вы обеспечиваете координаты для стартового расположения и конечного расположения, а также продолжительности, в секундах. Следующий пример указывает жест перетаскивания от расположения 160, 200 к расположению 160, 400, в течение 1 секунды:
UIATarget.localTarget().dragFromToForDuration({x:160, y:200}, {x:160, y:400}, 1); |
Жест щелчка подобен, но это, как предполагают, быстрое действие, таким образом, это не требует параметра продолжительности.
UIATarget.localTarget().flickFromTo({x:160, y:200}, {x:160, y:400}); |
Введение текста. Ваш сценарий должен будет, вероятно, протестировать тот Ваш ввод текста дескрипторов приложения правильно. Для этого это может ввести текст в текстовое поле путем простого указания поля целевого текста и установки его значения с setValue
метод. Следующий пример использует локальную переменную для обеспечения длинной строки как тестового сценария для первого текстового поля (индекс [0]) на текущем экране:
var recipeName = "Unusually Long Name for a Recipe"; |
UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0].setValue(recipeName); |
Навигация в приложении с вкладками. Для тестирования навигации между экранами в приложении необходимо будет очень вероятно коснуться вкладки в панели вкладок. Ответвление вкладки во многом как ответвление кнопки; Вы получаете доступ к надлежащей панели вкладок, указываете желаемую кнопку и касание что кнопка, как показано в следующем примере:
var tabBar = UIATarget.localTarget().frontMostApp().mainWindow().tabBar(); |
var selectedTabName = tabBar.selectedButton().name(); |
if (selectedTabName != "Unit Conversion") { |
tabBar.buttons()["Unit Conversion"].tap(); |
} |
Во-первых, локальная переменная, как объявляют, представляет панель вкладок. Используя ту переменную, сценарий получает доступ к панели вкладок, чтобы определить выбранную вкладку и получить имя той вкладки. Наконец, если имя выбранной вкладки соответствует имя желаемой вкладки (в этом случае “Преобразование Модуля”), касания сценария та вкладка.
Прокрутка к элементу. Прокрутка является значительной частью взаимодействия пользователя со многими приложениями. Автоматизация UI обеспечивает множество методов для прокрутки. Основные методы допускают прокрутку к следующему оставленному элементу, право, или вниз. Более сложные методы поддерживают большую гибкость и специфику в прокрутке действий. Один такой метод scrollToElementWithPredicate
, который позволяет Вам прокручивать к элементу, удовлетворяющему определенные критерии, которые Вы указываете. Этот пример получает доступ к надлежащему табличному представлению через иерархию элемента и прокручивает к рецепту в том табличном представлении, имя которого запускается с “Круга Черепахи”.
UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0] \ |
.scrollToElementWithPredicate("name beginswith 'Turtle Pie'"); |
Используя scrollToElementWithPredicate
метод позволяет прокручивать к элементу, точное имя которого не может быть известно.
Используя предикат функциональность может значительно развернуть возможность и применимость Ваших сценариев. Для получения дополнительной информации об использовании предикатов см. Руководство по программированию Предиката.
Другие полезные методы для гибкости в прокрутке включают scrollToElementWithName
и scrollToElementWithValueForKey
. Посмотрите Ссылку класса UIAScrollView для получения дополнительной информации.
Метка доступности и атрибуты идентификатора
Атрибут метки и атрибут идентификатора фигурируют заметно в возможности Вашего сценария получить доступ к элементам UI, таким образом, это - хорошая идея понять, как они используются.
Установка значимого значения для атрибута метки является дополнительной, но рекомендована. Можно установить и просмотреть строку метки в поле Текста метки в разделе Accessibility инспектора Идентификационных данных в Интерфейсном Разработчике. Эта метка, как ожидают, будет дескриптивной, но коротким, частично потому что вспомогательные технологии, такие как VoiceOver Apple используют ее в качестве имени связанного элемента UI. В Автоматизации UI эта метка возвращается label
метод. Это также возвращается name
метод как значение по умолчанию, если identifier
атрибут не установлен. Для обзора меток доступности посмотрите Тик Палец ноги Tac: Создание Доступных Приложений с Пользовательским UI и Руководства по программированию Доступности для iOS. Для ссылочных подробных данных посмотрите Ссылку класса UIAccessibilityElement.
Атрибут идентификатора позволяет Вам использовать более описательные имена для элементов. Это является дополнительным, но это должно быть установлено для сценария выполнить любую из этих двух операций:
Доступ к контейнерному представлению по имени, в то время как также способность получить доступ к ее дочерним элементам
Доступ к представлению UILabel по имени для получения его отображаемого текста (через его
value
атрибут)
В автоматизации UI, name
метод возвращает значение этого атрибута идентификатора, если Вы установлены. Если это не установлено, name
метод возвращает значение label
атрибут.
В настоящее время можно установить значение для атрибута идентификатора только программно, через accessibilityIdentifier
свойство. Для получения дополнительной информации посмотрите Ссылку на протокол UIAccessibilityIdentification.
Добавление синхронизации гибкости с периодами тайм-аута
При выполнении сценария тестирования попытка получить доступ к элементу может перестать работать по ряду причин. Например, действие могло перестать работать если:
Приложение находится все еще в процессе запуска.
Новый экран еще не был полностью нарисован.
Элемент (такой как кнопка, которую Ваш сценарий пытается нажать) может быть нарисован, но его содержание еще не заполнено в или обновленный.
В ситуациях как они Ваш сценарий, возможно, должен ожидать некоторого действия для завершения перед продолжением. В приложении Рецептов, например, пользователь касается вкладки Recipes для возврата от экрана Unit Conversion до экрана Recipes. Однако Автоматизация UI может обнаружить существование кнопки Add, позволив сценарию тестирования попытаться коснуться его — прежде чем кнопка будет фактически нарисована, и приложение фактически готово принять то касание. Точный тест должен гарантировать, что экран Recipes полностью нарисован и что приложение готово принять взаимодействие с пользователем со средствами управления в том экране перед продолжением.
Чтобы обеспечить некоторую гибкость в таких случаях и дать Вам более прекрасный контроль над синхронизацией, Автоматизация UI обеспечивает в течение периода тайм-аута, периода, в течение которого это неоднократно пытается выполнить указанное действие перед сбоем. Если действие завершается в течение периода тайм-аута, той строки возвратов кода, и Ваш сценарий может продолжиться. Если действие не завершается в течение периода тайм-аута, исключение выдается, и Автоматизация UI возвращает a UIAElementNil
объект. A UIAElementNil
объект всегда считают недопустимым.
Период тайм-аута по умолчанию составляет пять секунд, но Ваш сценарий может изменить это в любое время. Например, Вы могли бы уменьшить период тайм-аута, если Вы хотите протестировать, существует ли элемент, но не должен ожидать, если это не. С другой стороны, Вы могли бы увеличить период тайм-аута, когда сценарий должен получить доступ к элементу, но пользовательский интерфейс не спешит обновлять. Следующие методы для управления периодом тайм-аута доступны в классе UIATarget:
timeout
: Возвращает текущее значение тайм-аута.setTimeout
: Устанавливает новое значение тайм-аута.pushTimeout
: Хранит текущее значение тайм-аута на штабеле и устанавливает новое значение тайм-аута.popTimeout
: Получает предыдущее значение тайм-аута от штабеля, восстанавливает его как текущее значение тайм-аута и возвращает его.
Для создания этой функции максимально простой использовать Автоматизация UI использует модель штабеля. Вы продвигаете пользовательский период тайм-аута к вершине штабеля, как со следующим кодом, сокращающим период тайм-аута к двум секундам.
UIATarget.localTarget().pushTimeout(2); |
Вы тогда выполняете код, чтобы выполнить действие и вытолкать пользовательский тайм-аут от штабеля.
UIATarget.localTarget().popTimeout(); |
Используя этот подход Вы заканчиваете с устойчивым сценарием, ожидая разумное количество времени чего-то для случая.
Для получения дополнительной информации см. Ссылку класса UIATarget.
Журналирование результатов испытаний и данных
Ваш сценарий сообщает информацию журнала инструменту Автоматизации, собирающему его и сообщающему его для анализа.
При записи тестов необходимо зарегистрировать столько информации, сколько Вы можете, если только помочь Вам диагностировать какие-либо происходящие отказы. Как минимум, когда каждый тест начинается и заканчивается, идентифицируя тест выполняемое и записывающее состояние передачи/сбоя, необходимо зарегистрировать. Этот вид минимального журналирования является почти автоматическим в Автоматизации UI. Вы просто вызываете logStart
с именем Вашего теста, запущенного Ваш тест, затем вызывают logPass
или logFail
столь же надлежащий, как показано в следующем примере:
var testName = "Module 001 Test"; |
UIALogger.logStart(testName); |
//some test code |
UIALogger.logPass(testName); |
Но это - хорошая практика для журналирования то, что выясняется каждый раз, когда сценарий взаимодействует с управлением. Проверяете ли Вы это, части Вашего приложения выполняют должным образом, или Вы все еще разыскиваете ошибки, трудно предположить иметь слишком много информации о журнале для анализа. С этой целью можно зарегистрировать примерно любое использование возникновения logMessage
, и можно даже дополнить текстовые данные со снимками экрана.
Следующий пример кода разворачивает журналирование предыдущего примера для включения сообщения журнала свободной формы и снимка экрана:
var testName = "Module 001 Test"; |
UIALogger.logStart(testName); |
//some test code |
UIALogger.logMessage("Starting Module 001 branch 2, validating input."); |
//capture a screenshot with a specified name |
UIATarget.localTarget().captureScreenWithName("SS001-2_AddedIngredient"); |
//more test code |
UIALogger.logPass(testName); |
Снимок экрана, который требуют в примере, был бы сохранен назад к Инструментам и появился бы в Редакторе, Входят в систему подробная область с указанным именем файла (SS001-2_AddedIngredient.png
, в этом случае).
Используя снимки экрана
Ваш сценарий может получить снимки экрана с помощью captureScreenWithName
и captureRectWithName
методы в UIATarget
класс. Для обеспечения легкого доступа к тем снимкам экрана откройте раздел Logging слева от шаблона, выберите опцию Continuously Log Results и используйте Выбрать всплывающее меню Location для указания папки для результатов журнала. Каждый полученный снимок экрана сохранен в папке результатов с именем, указанным Вашим сценарием.
Проверка результатов испытаний
Затруднение тестирования является способностью проверить, что каждый тест был выполнен и что это или передало или перестало работать. Этот пример кода запускает тест testName
определить, существует ли допустимый элемент рецепта элемента, имя которого запускается с «Tarte», в табличном представлении рецепта. Во-первых, локальная переменная используется для указания критериев ячейки:
var cell = UIATarget.localTarget().frontMostApp().mainWindow() \ |
.tableViews()[0].cells().firstWithPredicate("name beginswith 'Tarte'"); |
Затем, сценарий использует isValid
метод, чтобы протестировать, существует ли допустимый элемент, соответствующий те критерии, в табличном представлении рецепта.
if (cell.isValid()) { |
UIALogger.logPass(testName); |
} |
else { |
UIALogger.logFail(testName); |
} |
Если допустимая ячейка найдена, код регистрирует сообщение передачи для testName
тест; в противном случае это регистрирует сообщение об отказе.
Заметьте, что этот тест указывает firstWithPredicate
и "name beginsWith 'Tarte'"
. Эти критерии уступают, ссылка на ячейку для “Tarte aux Обшивает рюшем”, который уже работает на данные по умолчанию в демонстрационном приложении Рецептов. Если, однако, пользователь добавляет рецепт для “Tarte aux Framboises”, этот пример может или может не дать желаемые результаты.
Обработка предупреждений
В дополнение к проверке, что предупреждения Вашего приложения выполняют должным образом, Ваш тест должен разместить предупреждения, неожиданно появляющиеся извне Вашего приложения. Например, весьма обычно получить текстовое сообщение, проверяя погоду или играя в игру.
Обработка внешне сгенерированных предупреждений
Несмотря на то, что это может казаться несколько парадоксальным, Ваше приложение и Ваши тесты должны ожидать, что неожиданные предупреждения произойдут каждый раз, когда работает Ваше приложение. К счастью, Автоматизация UI включает предупредительный обработчик по умолчанию, представляющий внешние предупреждения, очень простые для Вашего сценария справляться. Ваш сценарий обеспечивает предупредительную вызванную функцию-обработчик onAlert
, который вызывают, когда предупреждение произошло, в котором времени оно может принять любые соответствующие меры, и затем тогда просто возвратить предупреждение обработчику по умолчанию для увольнения.
Следующий пример кода иллюстрирует очень простой предупредительный случай:
UIATarget.onAlert = function onAlert(alert) { |
var title = alert.name(); |
UIALogger.logWarning("Alert with title '" + title + "' encountered."); |
// return false to use the default handler |
return false; |
} |
Весь этот обработчик делает зарегистрировать сообщение, что этот тип предупреждения был получен и затем возврат false
. Возврат false
направляет обработчик предупреждения значения по умолчанию Автоматизации UI, чтобы просто отклонить предупреждение. В случае предупреждения для полученного текстового сообщения, например, Автоматизация UI нажимает кнопку Close.
Обработка внутренне сгенерированных предупреждений
Как часть Вашего приложения, у Вас будут предупреждения, которые должны быть обработаны. В тех экземплярах Ваш предупредительный обработчик должен выполнить надлежащий ответ и возврат true
к обработчику по умолчанию, указывая, что было обработано предупреждение.
Следующий пример кода расширяется немного на основном предупредительном обработчике. После журналирования предупредительного типа это тестирует, является ли предупреждение определенным, это ожидается. Если так, это касается кнопки Continue, которая, как известно, существует, и возвраты true
пропускать действие увольнения по умолчанию.
UIATarget.onAlert = function onAlert(alert) { |
var title = alert.name(); |
UIALogger.logWarning("Alert with title '" + title + "' encountered."); |
if (title == "The Alert We Expected") { |
alert.buttons()["Continue"].tap(); |
return true; //alert handled, so bypass the default handler |
} |
// return false to use the default handler |
return false; |
} |
Этот основной предупредительный обработчик может быть обобщен для ответа на примерно любое полученное предупреждение, позволяя сценарию продолжать работать.
Обнаружение и указание ориентации устройства
Приложение для iOS хорошего поведения, как ожидают, обработает изменения в ориентации устройства корректно, таким образом, Ваш сценарий должен будет ожидать и протестировать на такие изменения.
Автоматизация UI обеспечивает setDeviceOrientation
моделировать изменение в ориентации устройства. Этот метод использует константы, перечисленные в Таблице 11-1.
Постоянная ориентация | Описание |
---|---|
UIA_DEVICE_ORIENTATION_UNKNOWN | Ориентация устройства не может быть определена. |
UIA_DEVICE_ORIENTATION_PORTRAIT | Устройство находится в режиме портрета с устройством вертикально и кнопкой «Домой» в нижней части. |
UIA_DEVICE_ORIENTATION_PORTRAIT_UPSIDEDOWN | Устройство находится в режиме портрета, но вверх тормашками с устройством вертикально и кнопкой «Домой» наверху. |
UIA_DEVICE_ORIENTATION_LANDSCAPELEFT | Устройство находится в альбомном режиме с устройством вертикально и кнопкой «Домой» на правой стороне. |
UIA_DEVICE_ORIENTATION_LANDSCAPERIGHT | Устройство находится в альбомном режиме с устройством вертикально и кнопкой «Домой» на левой стороне. |
UIA_DEVICE_ORIENTATION_FACEUP | Устройство параллельно земле со смотрящим вверх экраном. |
UIA_DEVICE_ORIENTATION_FACEDOWN | Устройство параллельно земле со смотрящим вниз экраном. |
В отличие от устройства ориентация является интерфейсной ориентацией, представляющей вращение, требуемое сохранить интерфейс Вашего приложения ориентированным должным образом после вращения устройства. Обратите внимание на то, что в альбомном режиме, ориентация устройства и интерфейсная ориентация противоположны, потому что вращение устройства требует вращения содержания в противоположном направлении.
Автоматизация UI обеспечивает interfaceOrientation
метод для получения текущей интерфейсной ориентации. Этот метод использует константы, перечисленные в Таблице 11-2.
Постоянная ориентация | Описание |
---|---|
UIA_INTERFACE_ORIENTATION_PORTRAIT | Интерфейс находится в режиме портрета с нижней частью, самой близкой к кнопке «Домой». |
UIA_INTERFACE_ORIENTATION_PORTRAIT_UPSIDEDOWN | Интерфейс находится в режиме портрета, но вверх тормашками с вершиной, самой близкой к кнопке «Домой». |
UIA_INTERFACE_ORIENTATION_LANDSCAPELEFT | Интерфейс находится в альбомном режиме с левой стороной, самой близкой к кнопке «Домой». |
UIA_INTERFACE_ORIENTATION_LANDSCAPERIGHT | Интерфейс находится в альбомном режиме с правой стороной, самой близкой к кнопке «Домой». |
Следующий пример изменяет ориентацию устройства (в этом случае, к оставленной среде), затем возвращает его (к портрету):
var target = UIATarget.localTarget(); |
var app = target.frontMostApp(); |
//set orientation to landscape left |
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_LANDSCAPELEFT); |
UIALogger.logMessage("Current orientation now " + app.interfaceOrientation()); |
//reset orientation to portrait |
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_PORTRAIT); |
UIALogger.logMessage("Current orientation now " + app.interfaceOrientation()); |
Конечно, как только Вы вращались, действительно необходимо вращаться назад снова.
При выполнении теста, включающего изменение ориентации устройства, это - хорошая практика, чтобы установить вращение в начале теста, затем задержать его к исходному вращению в конце теста. Эта практика гарантирует, что Ваш сценарий всегда вернулся в известном состоянии.
Вы, возможно, заметили ориентацию, входящую в систему пример. Такое журналирование обеспечивает дополнительное обеспечение, что Ваши тесты — и Ваши тестеры — не становятся дезориентированными.
Тестирование на многозадачность
Когда пользователь выходит из Вашего приложения, касаясь кнопки «Домой» или заставляя некоторое другое приложение прибыть в передний план, Ваше приложение приостановлено. Для моделирования этого возникновения Автоматизация UI обеспечивает deactivateAppForDuration
метод. Вы просто вызываете этот метод, указав продолжительность, в секундах, за которые Ваше приложение должно быть приостановлено, как проиллюстрировано следующим примером:
UIATarget.localTarget().deactivateAppForDuration(10); |
Эта одна строка кода заставляет приложение быть деактивированным в течение 10 секунд, как если бы пользователь вышел из приложения и возвратился к нему 10 секунд спустя.
Выполнение сценария тестирования из проекта XCode
Можно легко автоматизировать выполнение сценария тестирования путем создания пользовательского инструментального шаблона Автоматизации.
Создание пользовательского инструментального шаблона автоматизации
Создать пользовательский инструментальный шаблон Автоматизации:
Запустите Инструментальное приложение.
Выберите шаблон Automation для создания документа трассировки.
Выберите View> Detail, при необходимости, для отображения подробного представления.
Выберите свой сценарий из списка.
Отредактируйте свой сценарий по мере необходимости в области Script подробной области.
Выберите File> Save как Шаблон, назовите шаблон и сохраните его к расположению шаблона Instruments по умолчанию:
~/Library/Application Support/Instruments/Templates/
Выполнение инструментального сценария автоматизации в XCode
После создания специализированного шаблона Automation можно выполнить сценарий тестирования от XCode путем выполнения этих шагов:
Откройте свой проект в XCode.
От всплывающего меню Схемы (на панели инструментов окна рабочей области), выберите Edit Scheme для схемы, с которой требуется использовать сценарий.
Выберите Profile из левого столбца схемы, редактируя диалоговое окно.
Выберите свое приложение из Исполнимого всплывающего меню.
Выберите свой специализированный шаблон Automation Instrument из Инструментального всплывающего меню.
Нажмите «OK», чтобы утвердить Ваши изменения и уволить редактора схемы диалоговое окно.
Выберите Product> Profile.
Инструменты запускают и выполняют Ваш сценарий тестирования.
Выполнение инструментального сценария автоматизации из командной строки
Можно также выполнить сценарий тестирования из командной строки. При создании специализированного шаблона Automation, как описано в Создании Пользовательского Инструментального Шаблона Автоматизации можно использовать следующую простую команду:
instruments -w deviceID -t templateFilePath targetAppName
deviceID
Идентификатор с 40 устройствами посимвольного ввода-вывода, доступный в организаторе Устройств XCode, и в iTunes.
templateFilePath
Полный путь Вашего специализированного шаблона Automation, по умолчанию,
~/Library/Application Support/Instruments/Templates/templateName
, гдеtemplateName
имя, с которым Вы сохранили его.targetAppName
Локальное имя приложения. При предназначении для устройства опустите путь и
.app
расширение. При предназначении для средства моделирования используйте полный путь.
Если Вы не хотите создавать пользовательский, можно использовать шаблон трассировки по умолчанию. Для этого Вы используете переменные окружения UIASCRIPT
и UIARESULTSPATH
идентифицировать сценарий и каталог результатов.
instruments -w deviceID -t defaultTemplateFilePath targetAppName \ |
-e UIASCRIPT scriptFilePath -e UIARESULTSPATH resultsFolderPath |
defaultTemplateFilePath
Полный путь шаблона по умолчанию:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Instruments/PlugIns/
AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate
scriptFilePath
Расположение файловой системы Вашего сценария тестирования.
resultsFolderPath
Расположение файловой системы каталога для содержания результатов сценария тестирования.