Объект
Selenium RC: Дружим с XPath
Опубликовано KaNoN в 20.09.2010При работе с Selenium доступ к объектам осуществляется через локаторы - строки, идентифицирующие объект, над которым проводится то или иное действие. Наиболее удобными и наиболее быстрыми являются локаторы, определенные по ID объекта ( у каждого объекта на HTML странице может быть определен атрибут ID, причем он должен быть уникальным ). Ну уж если не определен ID, то как минимум для элементов форм есть атрибуты Name, через которые тоже достаточно удобно и просто работать. Но в общем случае, приходится работать с большим многообразием объектов, причем и действия приходится делать самые разнообразные. Например:
- на странице есть несколько полей с одинаковым атрибутом Name, но у разных форм и нужно работать с конкретным полем конкретной формы.
- на странице множество объектов сходной структуры и их надо обработать одинаково (например, очистить все текстовые поля)
- нужно обработать одинаковым образом все объекты, которые характеризуются определенным текстов некоторых дочерних объектов (например, мы знаем заголовки таблицы, а нужно сделать клик на ссылке, которая находится на том же уровне)
Каждый отдельно взятый случай решает данные проблемы своими путями, но более-менее универсальным решением является использование XPath. В чем его удобство.
- Во-первых, данный способ задания местоположения объекта оперирует с фактическими HTML-тегами, что дает возможность формировать локаторы исходя из непосредственно HTML-кода страницы, который можно просмотреть.
- Во-вторых, есть возможность задать некоторую иерархию объектов, при этом пропустить варьируемые элементы (удобно, когда надо вычислить элемент внутри таблицы, не привязываясь к конкретным ячейкам).
- В-третьих, элемент можно задать используя как теги, так и определенные значения атрибутов, причем можно проверить на частичное соответствие (удобно, когда элемент уникально идентифицируется обработчиком некоторого события).
- В-четвертых, в Selenium есть отдельный метод, который позволит нам узнать количество элементов, удовлетворяющих заданному XPath, а такде возможность использовать индексы, что позволяет выделить и перебирать целую коллекцию элементов.
А теперь перейдем к практической составляющей. Допустим, у нас есть набор различных графиков в виде bar-chart или pie-chart, причем при клике на каждый элемент происходит переход на некоторую страницу. Реализация в HTML подобного имеет вид:
<map>
<area href="ref1">
<area href="ref2">
<area href="ref3">
...
<area href="ref1">
<img src="some_img.gif">
</map>вот таких map-блоков произвольное количество. В каждом из этих блоков произвольное количество элементов area. Но везде есть ссылки и на эти area-объекты мы можем сделать клик. Итак, как можно организовать обработку всех активных областей всех диаграмм. Вначале, мы узнаем, сколько же всего этих диаграмм присутствует. Предположим, что у нас уже есть проинициализированный объект Selenium-a и мы уже на нужной странице. Соответственно, реализация имеет вид (далее все примеры приводятся с использованием синтаксиса Java, но по аналогии переносится на остальные языки, на которых реализован Selenium-клиент):
int chartsCount = selenium.getXPathCount( "//map" ).intValue();
»
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
- Читать далее
Синхронизация в автотестах. Часть 2: ожидание одного из возможных событий
Опубликовано KaNoN в 01.09.2010Часто при работе автотестов возникают ситуации, когда приложение может вести себя по-разному и в зависимости от полученной реакции приложения нужно выполнить определенные действия. Наиболее четко это выражено в тестировании GUI, когда после выполнения некоторых операций мы ожидаем один из возможных вариантов реакции системы. Самый простой пример: у нас есть окно Notepad и нам надо реализовать функционал по его закрытию. То есть, нужно нажать на крестик в правом верхнем углу. Но если уже был введен некоторый текст, то вначале появится сообщение о подтверждении сохранения изменений. В этом случае нам дополнительно надо еще обработать диалог закрытия окна. Если подобную задачу реализовывать в виде некоторой вспомогательной функции, то обе ситуации надо обрабатывать.
Безусловно, эту обработку можно делать последовательно. В случае с вышеприведенным примером можно после нажатия крестика проверить наличие окна сообщения, выполнить действия при появлении этого окна, а затем уже спокойно ждать закрытия главного окна. Но уже в этом простом примере наблюдается неэффективное использование времени выполнения. Если окна подтверждения сохранения нет, то мы потратим впустую некоторое время на его ожидание. Опять же, был описан достаточно простой случай, но может так случиться, что один и тот же функционал работает по-разному в зависимости от настроек, при этом нужно реализовать универсальную функцию. В этом случае последовательная обработка разных объектов может оказаться неспособной реализовать поставленную задачу.
Наиболее эффективным решением с точки зрения рационального оспользования времени выполнения является последовательный опрос требуемых объектов втечение заданного промежутка времени. То есть, если применить псевдо-код, то реализация описывается следующим фрагментом:
startTimer();
while( getElapsedTime() > iTimeout ){
i = 0;
foreach control in ( controlList ){
if( control.property == expected ){
return i;
}
}
}
return -1;В этом примере:
- startTimer() - инициирует работу таймера
- getElapsedTime() - возвращает время прошедшее с момента инициации таймера
- iTimeout - максимальное время ожидания
- expected - ожидаемое значение некоторого проверяемого свойства
- controlList - список элементов управления, у которых надо проверить значение property на соответствие значению expected.
»
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
- Читать далее
Синхронизация в автотестах. Часть 1
Опубликовано KaNoN в 30.08.2010Одной из наиболее серьезных проблем при разработке автотестов ( особенно функциональных на уровне GUI ) является синхронизация выполнения тестов с работой тестируемого приложения. Иными словами, действия, которые выполняются в автоматическом тесте, должны осуществляться именно в тот момент, когда приложение находится в требуемом для данного действия состоянии. В противном случае мы можем получить картину, когда тест пытается делать клики, вводить текст, в то время как форма, над которой осуществляются данные действия, отсутствует. В результате, наш тест идет проторенными методами, но совсем непонятными путями. Если при этом нет никаких механизмов выравнивания состояния, то подобное может серьезно подкосить выполнение пакета тестов в целом.
Как результат, нужно обеспечить темп работы теста таким образом, чтобы он соответствовал темпу работы тестируемого приложения. Как это сделать?
Наиболее простым вариантом является установка задержек. Практически во всех средствах для автоматизации функционального тестирования есть инструкции, которые просто делают паузу в выполнении. Так, во многих решениях присутствуют функции вида: sleep( nSec ) или wait( nSec ). В TestComplete это делается вызовом BuiltIn.Delay(), в Java для этого есть вызов Process.sleep( ). Все эти решения имеют схожую структуру - единственный параметр, указывающий время, на которое установить паузу.
Преимущества данного решения:
- Простота - использование встроенной функции/метода достаточно простое и понятное
- В некоторых случаях подобные вставки позволяют избежать "заклинивания" выполнения, когда 2 достаточно ресурсоемкие операции выполняются друг за другом ( в частности в SilkTest в некоторых случаях пауза в 1 секунду позволяла избегать заклинивания выполнения команд Агента ).
- Достаточно эффективное решение для операций, которые имеют фиксированное время "опоздания", например, появление окна сообщения, выданного клиентским скриптом на веб-странице. В этом случае пауза нужна просто для того, чтобы четко синхронизировать тест с моментом точного появления окна
Тем не менее, у данного решения есть и недостатки:
- Нерациональное использование времени выполнения - некоторые операции, особенно, обработка различных клиент-серверных запросов, могут занимать различное время, даже для одной и той же команды. Соответственно, паузу целесообразно делать на интервал времени, покрывающий максимальное время ожидания. В результате, если действие выполнилось раньше, то пауза все равно действует фиксированное время, отчего мы теряем до нескольких минут на одном подобном ожидании. Если подобных действий будет много, то суммарная потеря времени выполнения будет составлять вплоть до нескольких часов.
- На разных средах тестируемое приложение может работать с разной скоростью, соответственно, нужно во всех вхождениях инструкции для паузы перестраивать время ожидания.
- Подобные паузы не отражают причин, по которым они проставлены, из-за чего подобный код весьма затруднительно читать. Также в тестовом коде может быть слишком много подобных инструкций, отчего код разрастается весьма ощутимо без видимых на то причин
- Подобные паузы не гарантируют, что тестируемое приложение достигло нужного состояния
Автоматизированное тестирование автотестов
Опубликовано KaNoN в 12.08.2010Автоматизированное тестирование програмного обеспечения может выражаться в разных формах с точки зрения целей, подходов и реализации. Но суть одна: автотесты - это програмные модули, позволяющие проверить поведение тестируемого приложения на соответствие требованиям или предоставляющие достаточно информации, чтобы осуществить подобную проверку (те же тесты на производительность вполне могут ограничиться выдачей статистики, которую потом анализирует человек ). Ключевым моментов является то, что автотесты - это такое же по сути програмное обеспечение, что и непосредственно тестируемое приложение, из чего следует, что автотесты точно так же могут содержать в себе ошибки реализации. То есть, их тоже не мешало бы периодически проверять на работоспособность или хотя бы установить какие-то средства контроля, поскольку тесты не менее чувствительны к изменениям тестируемого приложения, чем другие программные модули, затронутые в ходе изменений.
Отчасти вероятность ошибки в автотестах уменьшается за счет простоты автотестов. В частности, white-box тесты во многих случаях представляют собой несложные конструкции, которые вызывают тестируемый модуль и перехватывают исключения и/или обрабатывают код возврата. То есть, это во многом укладывается в шаблон. Функциональные тесты в большинстве случаев представляют собой линейный сценарий.
Тем не менее, автотесты могут использовать вспомогательные решения и компоненты, как непосредственно тестовый движок, дополнительные функции/методы, реализующие некоторый отдельно взятый функционал, а также оконные декларации, если речь заходит про GUI тестирование. Всё это может однажды дать сбой за счет изменений тестируемого приложения, окружения и прочих внешних факторов. И было бы очень полезно локализовать проблему непосредственно в том месте, где она возникла.
Теперь рассмотрим, что и как мы можем автоматически протестировать:
- Непосредственно автотесты - динамически такие компоненты проверяются непосредственно во время тестовых запусков, что не выделяет тестирование автоматизированных решений из контекста автоматизированного тестирования, для которого это тесты предназначены. Проще говоря, наиболее эффективный способ проверить работоспособность автотестов - это выполнить эти автотесты.
- Вспомогательные классы/функции/методы - поскольку подобные компоненты представляют собой некоторый программный код, то ничто не мешает применить для них традиционные практики white-box тестирования.
- Оконные объекты - этот тип компонентов специфичен для автоматизированного тестирования, в частности GUI-level тестирования и один из наиболее критичных к изменениям тестируемого приложения. Поэтому, для тестирования подобных компонент следует выработать некоторый workflow-сценарий, который затронет все ( или хотя бы просто большинство ) оконных объектов
Как это внедрять? Внедрить это можно на этапе разработки. Например, при разработке вспомогательных классов для автотестов можно использовать практику TDD для контроля качества создаваемого компонента. Это позволит сформировать набор тестов, которые потом можно запускать непосредственно перед запусками основных автотестов. Это так называемое юнит-тестирование автоматизационного решения.
»
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
- Читать далее








