AT.info ПОСИДЕЛКИ  vKontakte   facebook группа  
Знаешь как делать? Можешь рассказать? Да! Мы тебя ждем.
view counter
Ищешь как решить проблему с Selenium?! Спроси людей. Они все знают!
view counter
Очень хочется узнать его. Форум ждет тебя!
view counter
Принцип

Глобальная стратегия автоматизации. 10 ключевых моментов, которые должны помнить руководители

Глобальная автоматизация тестирования - стратегия, которая интегрирует тестирование программного обеспечения вручную, автоматизацию тестирования, и глобальные стратегии ресурса для того, чтобы максимизировать преимущества тестирования программного обеспечения одновременно уменьшая затраты. Существует десять ключевых моментов, которые необходимо помнить руководителям, при осуществлении стратегии глобальной автоматизации тестирования. Все они перечислены в этой статье.

Глобальная автоматизация тестирования: десять ключевых моментов, о которых нужно помнить

 

Стратегия глобальной автоматизации тестирования повысит прибыль и снизит затраты

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

  1. глобальная автоматизация тестирования обеспечит уверенность в постоянности и надежности разрабатываемого продукта на любом из этапов цикла разработки
  2. глобальная автоматизация тестирования позволит посвятить больше времени разработке и меньше обслуживанию
  3. глобальная автоматизация тестирования позволит вам эффективнее использовать ресурсы и бюджет благодаря своевременному получению
  4. глобальная автоматизация тестирования позволит сделать больше, ведь это будет дешевле
  5. глобальная автоматизация тестирования позволит Вам получить больше результатов
  6. глобальная автоматизация тестирования снижает возникновение трудоёмких и дорогостоящих "неожиданностей"

Архитектура автоматизации: Таблицы на основе пользовательского интерфейса

Проблема: Как специалисты без знания программирования могут сами создавать автоматизированные тесты?

Решение: Используйте таблицы где будут определены свойства окон, элементы на окнах, действия и данные для тестов.

Контекст:

  • Участники: Эксперты предметной области с поддержкой специалистов автоматизаторв, которые реализуют данную архитектуру.
  • Продукт: Пользовательский интерфейс уже определен ранее и находится в рабочем состоянии.
  • Цели: тестирование продукта с точки зрения бизнес пользователя

Стратегия тестирования:
Создание тестов:

  • Специалисты предметной области пошагово планируют тесты, оформляя их в таблицы.
  • Тесты могут быть записаны и финализированны как только пользовательский интерфейс будет известен. (другими словами, как только все готово для проведения тестоварония).

Выполнение тестов:

  • Интерпретатор и «диспетчер» выполняют тесты.

Оценка:

  • Ожидаемые результаты определяет автор теста.

Атрибуты качества:

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

Следующий шаг:
«Ключевые слова-действия» строятся на этом подходе.

Синхронизация в автотестах. Часть 2: ожидание одного из возможных событий

Часть 1

Часто при работе автотестов возникают ситуации, когда приложение может вести себя по-разному и в зависимости от полученной реакции приложения нужно выполнить определенные действия. Наиболее четко это выражено в тестировании 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

Часть 2

Одной из наиболее серьезных проблем при разработке автотестов ( особенно функциональных на уровне GUI ) является синхронизация выполнения тестов с работой тестируемого приложения. Иными словами, действия, которые выполняются в автоматическом тесте, должны осуществляться именно в тот момент, когда приложение находится в требуемом для данного действия состоянии. В противном случае мы можем получить картину, когда тест пытается делать клики, вводить текст, в то время как форма, над которой осуществляются данные действия, отсутствует. В результате, наш тест идет проторенными методами, но совсем непонятными путями. Если при этом нет никаких механизмов выравнивания состояния, то подобное может серьезно подкосить выполнение пакета тестов в целом.

Как результат, нужно обеспечить темп работы теста таким образом, чтобы он соответствовал темпу работы тестируемого приложения. Как это сделать?

Наиболее простым вариантом является установка задержек. Практически во всех средствах для автоматизации функционального тестирования есть инструкции, которые просто делают паузу в выполнении. Так, во многих решениях присутствуют функции вида: sleep( nSec ) или wait( nSec ). В TestComplete это делается вызовом BuiltIn.Delay(), в Java для этого есть вызов Process.sleep( ). Все эти решения имеют схожую структуру - единственный параметр, указывающий время, на которое установить паузу.

Преимущества данного решения:

  1. Простота - использование встроенной функции/метода достаточно простое и понятное
  2. В некоторых случаях подобные вставки позволяют избежать "заклинивания" выполнения, когда 2 достаточно ресурсоемкие операции выполняются друг за другом ( в частности в SilkTest в некоторых случаях пауза в 1 секунду позволяла избегать заклинивания выполнения команд Агента ).
  3. Достаточно эффективное решение для операций, которые имеют фиксированное время "опоздания", например, появление окна сообщения, выданного клиентским скриптом на веб-странице. В этом случае пауза нужна просто для того, чтобы четко синхронизировать тест с моментом точного появления окна

Тем не менее, у данного решения есть и недостатки:

  1. Нерациональное использование времени выполнения - некоторые операции, особенно, обработка различных клиент-серверных запросов, могут занимать различное время, даже для одной и той же команды. Соответственно, паузу целесообразно делать на интервал времени, покрывающий максимальное время ожидания. В результате, если действие выполнилось раньше, то пауза все равно действует фиксированное время, отчего мы теряем до нескольких минут на одном подобном ожидании. Если подобных действий будет много, то суммарная потеря времени выполнения будет составлять вплоть до нескольких часов.
  2. На разных средах тестируемое приложение может работать с разной скоростью, соответственно, нужно во всех вхождениях инструкции для паузы перестраивать время ожидания.
  3. Подобные паузы не отражают причин, по которым они проставлены, из-за чего подобный код весьма затруднительно читать. Также в тестовом коде может быть слишком много подобных инструкций, отчего код разрастается весьма ощутимо без видимых на то причин
  4. Подобные паузы не гарантируют, что тестируемое приложение достигло нужного состояния

Selenium RC (Java): Основные операции в действии. Часть 2

Часть 1, Часть 3

Работа с полем загрузки файлов

Одним из каверзных стандартных элементов управления на веб-страницах с точки зрения работы Selenium-a является поле загрузки файла. Фактически это текстовое поле и кнопка. В чем сложность? Сложность в том, что нажатие на кнопку Selenium-ом напрямую не делается (да и не нужно, если так посмотреть), а текстовое поле в общем случае доступно только для чтения, так что просто так ввести туда путь к файлу не получится. Это связано с тем, что Selenium-сервер взаимодействует с тестируемым веб-приложением путем посылки JavaScript-команд, а у объектов, соответствующих полям ввода файлов, атрибут value закрыт для записи. Это стандартное ограничение браузеров, блокирующее возможность автоматической загрузки произвольных файлов. Не стоит забывать, что клиентские скрипты несут в себе много чего вредоносного. Отчасти поэтому те же файлы с расширением js многими почтовиками блокируются. Это просто система защиты.

Тем не менее, данные проблемы так или иначе можно обойти. Итак, рассмотрим следующую секцию нашей тестовой страницы:

Реализуем шаг, в котором нам надо ввести некоторый текст в поле ввода файла и проверить, что текст введен корректно. Есть 2 способа ввести текст:

  • platform-specific - заключается в использовании сторонних библиотек, которые имитируют ввод с клавиатуры. В частности для Java можно воспользоваться классом java.awt.Robot.
  • browser-specific - заключается в том, что для определенных браузеров в определенном режиме поле ввода файлов доступно для записи на программном уровне. В частности, в режиме *chrome Selenium в состоянии ввести текст в поле ввода файла обычным вызовом type.

Из этих 2-х способов предпочтительнее выглядит 2-й по ряду причин. Во-первых, нет привязки к языку программирования, соответственно, данный подход универсален в контексте используемого языка программирования. Во-вторых, зачастую, использование внешних средств, имитирующих пользовательский ввод, привязывает код к конкретной группе операционных систем. И наконец, в-третьих, в большинстве случаев имитация ввода сводится к посылке некоторых сигналов "в эфир". Соответственно, если нужное нам окно не активно, то текст введется неизвестно куда. А ведь одно из удобств Selenium-a заключается в том, что тесты могут выполняться в фоновом режиме, в то время как пользователь может на той же машине заниматься своими делами.

Итак, нам нужно перейти в *chrome-режим, открыть страницу и ввести текст. Как-то так:

Selenium RC (Java): Основные операции в действии. Часть 1

Часть 2

В стандартной документации к селениуму достаточно много примеров тестов, но они в основном направлены на то, чтобы показать структуру тестов, а также некоторый частный случай использования тех или иных операций. При этом мало внимания уделяется обзору имеющихся команд. И это в принципе неудивительно, так как по сути мы используем один клиентский класс, у которого определены все необходимые нам методы. И уже в зависимости от конкретной задачи мы просто ищем нужный метод, который бы эту задачу выполнил. Тем не менее, мелких деталей всегда хватает и на их разбор может уйти много времени, что может вызвать множество проблем, особенно для начинающих. Поэтому, целью данного поста является ознакомление с основными операциями селениума, с которыми так иил иначе придется иметь дело, а также описание возможных нюансов, которые могут возникнуть.

Мы будем рассматривать работу селениума на примере Java клиента, но все подходы и заморочки аналогичны для других языков. Также, изначально предполагается, что селениум-сервер и клиентские библиотеки уже установлены и настроены нужным образом, так что на эти вещи мы не будем отвлекаться. Если у вас с этим есть проблемы, то для начала вам сюда. Также желательно быть знакомым с Java, хотя бы на базовом уровне, так как данный пост не предназначен для введения в Java.

В качестве основы теста мы возьмем пример отсюда, оставим каркас и наполним конструкциями для нашего теста. Об этом чуть позже.

Для нашего примера нужно создать тестовый HTML файл, в котором будут основные элементы, с которыми мы будем работать. Создадим файл index.htm и поместим его в корневой каталог диска C: . Если вы хотите поместить этот файл в другой каталог, то вам надо будет просто поменять абсолютный путь к файлу и учитывать это вдальнейшем при рассмотрении данного примера.

Итак, поместим в наш HTML-файл содержимое вида:

<html>
<body>
	<form name="sample_form">
		<table>
		<tr><td width="100%"><fieldset><legend>Text fields</legend>
			<table>
				<tr>
					<td><label for="text_field">Simple text field:</td>
					<td><input type=text id="text_field" value="" /></td>
				</tr>
				<tr>
					<td valign=top><label for="text_area">Text Area:</td>
					<td><textarea id="text_area" name="text_area" cols=30 rows=5></textarea></td>
				</tr>
			</table>
		</fieldset></td></tr>
		<tr><td width="100%"><fieldset><legend>Radio buttons/Check boxes</legend>
			<table>
				<tr>
					<td><label for="radio_1">Item 1:</td>
					<td><input type=radio id="radio_1" name="radio_btn" checked /></td>
				</tr>
				<tr>
					<td><label for="radio_2">Item 2:</td>
					<td><input type=radio id="radio_2" name="radio_btn"/></td>
				</tr>
				<tr>
					<td valign=top><label for="check_box">Check box:</td>
					<td><input type=checkbox name="check_box" /></td>
				</tr>
				<tr>
					<td valign=top><label for="ev_check_box">Check box with event:</td>
					<td><input type=checkbox name="ev_check_box" onclick="deactivated_btn.disabled=!this.checked;"/></td>
				</tr>

			</table>
		</fieldset></td></tr>

		<tr><td width="100%"><fieldset><legend>Buttons</legend>
			<table>
				<tr>
					<td><b><div id="clicked_text"></div></b></td>
				</tr>
				<tr>
					<td>
					<input type=button id="deactivated_btn" value="Deactivated" onclick="clicked_text.innerHTML=deactivated_btn.value;"/>
					<input type=button id="btn_1" value="First"  onclick="clicked_text.innerHTML=btn_1.value;"/>
					<button id="btn_2" onclick="clicked_text.innerHTML=btn_2.innerHTML;return false;">Second</button>
					</td>
				</tr>

			</table>
		</fieldset></td></tr>
		<tr><td width="100%"><fieldset><legend>Lists</legend>
			<table>
				<tr>
					<td><label for="single_list">Single selection list:</td>
					<td>
					<select id="single_list" />
						<option selected>Option 1</option>
						<option>Option 2</option>
						<option>Option 3</option>
					</select>
					</td>
				</tr>
				<tr>
					<td valign=top><label for="multi_list">Multi selection list:</td>
					<td>
						<select id="multi_list" MULTIPLE>
						<option>Multi Option 1</option>
						<option>Multi Option 2</option>
						<option>Multi Option 3</option>
						</select>
					</td>
				</tr>
			</table>
		</fieldset></td></tr>
		<tr width="100%"><td width="100%"><fieldset><legend>File input</legend>
			<table>
				<tr>
					<td valign=top><label for="file_input">File upload:</td>
					<td><input type=file name="file_field" /></td>
				</tr>
			</table>

		</fieldset></td></tr>

		<tr><td><fieldset><legend>Dialog boxes</legend>
			<table>
				<tr>
					<td>
						<input type=button id="alert_btn" value="Call Alert"onclick="alert('This is Alert');"/>
						<input type=button id="conf_btn" value="Call Confirmation"  onclick="confirm('This is confirmation');"/>
						<input type=button id="prompt_btn" value="Call Prompt"  onclick="prompt('Enter prompt text')"/></td>
				</tr>
			</table>

		</fieldset></td></tr>

		</table>
	</form>
</body>
</html>

Достаточно просто скопировать данный текст и вставить его в нужный HTML-файл.

Осталось только создать тестовый класс, в котором мы будем добавлять код. Создайте пакет com.example.tests и создайте в нем класс NewTest, который наследуется от SeleneseTestCase класса. После этого каркас теста имеет вид:

package com.example.tests;
// We specify the package of our tests

import com.thoughtworks.selenium.*;
// This is the driver's import. You'll use this for instantiating a
// browser and making it do what you need.

import java.util.regex.Pattern;
// Selenium-IDE add the Pattern module because it's sometimes used for
// regex validations. You can remove the module if it's not used in your
// script.

public class NewTest extends SeleneseTestCase {
// We create our Selenium test case

      public void setUp() throws Exception {
        setUp("c:\\index.htm", "*firefox");
             // We instantiate and start the browser
      }

      public void testNew() throws Exception {
           selenium.open("c:\\index.htm");
     }
}

Этот каркас взят из примеров в документации к селениуму. Просто были сделаны небольшие корректировки. Итак, приступаем.

"Подводные камни" автоматизации тестирования

Статья является модификацией более ранней версии, опубликованной в журнале “Windows Tech Journal”(10/96) и протоколами 14й Международной Конференции в Тестировании Программного Обеспечения, соответственно. Автор благодарит ST Labs за поддержку.

Ситуация 1. Во время разработки продукт передается от одного разработчика к другому. Каждый новый разработчик обнаруживает, что документация к продукту уже устарела и процесс разработки нарушен. После анализа в течение месяца каждый объявлял о неудачном проектировании и настаивал на необходимости написания больших объемов нового кода. По прошествии еще нескольких месяцев разработчик уходил или продукт передавался другому человеку, и весь процесс повторялся заново.

Ситуация 2. Программисты быстро реализовали проект без достаточного понимания того, какие же задачи он должен был решать. Спустя много месяцев после завершения, при анализе результатов обнаруживается, что система в эксплуатации и обслуживании стоит дороже, чем проведение того же процесса, который система автоматизировала, вручную.

Ситуация 3. 100000$ было потрачено на внедрение современного набора инструментов для разработки. Вскоре обнаружилось, что данные инструменты не настолько мощные, портативные, надежные, чтобы использовать их для достижения значительных успехов в разработке. После ближайших двух лет попыток заставить их работать, инструменты были заброшены.

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

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

Эти небольшие эпизоды из моей собственной практики, но я уверен, что они знакомы многим. Это распространенные жалобы на то, что многие программные продукты проваливаются. И это не должно нас удивлять – со стороны, программы кажутся очень простыми, но ведь проблема в деталях, не так ли? Опытные разработчики программного обеспечения отлично это знают, и к началу нового проекта подходят настороженно и скептично.

Автоматизация тестирования также непроста. Рассмотрим еще раз ситуации, приведенные ранее. В основном, каждый из этих случаев был попыткой автоматизировать тестирование. Девять лет я управлял группами по тестированию программного обеспечения и занимался автоматизацией тестирования (имейте ввиду, в компаниях богатых и разбирающихся в разработке программных продуктов). Наиболее важным открытием для меня стало то, что проекты тестирования программного обеспечения настолько же близки к краху, как и любые другие программные продукты. По сути, в моем опыте, они проваливались чаще, в основном, потому что большинство организаций не уделяло такой же заботы и профессионализма для тестовых продуктов, как делалось это в текущих проектах.

Странно, что почти все эксперты по тестированию, практикующие тестировщики, менеджеры по тестированию, и, конечно же, компании, продающие инструменты для тестирования, рекомендуют автоматизировать тестирование с таким чрезвычайным энтузиазмом. Хотя, возможно, «странно» не совсем правильное слово. В итоге, инструменты для автоматизации проектирования и разработки были огромной прихотью, и инструменты для тестирования просто другая сторона таких продуктов. От объектно-ориентированного до «безпрограммистского» программирования, идеалистическая пропаганда не новость в нашей индустрии. Так, может, высокое качество общедоступной информации и анализа автоматизации тестирования не такое уж удивительное, а скорее, просто знак незрелости данной области. Как сообщество приверженцев автоматизации, возможно, мы еще в фазе восхищения идеей автоматизации тестирования, но еще не разобрались в подводных камнях. Поспешу согласиться, что автоматизация – это отличная идея. Мне нравиться что-то автоматизировать гораздо больше, чем выполнять какие-либо другие задачи. Большинство тестировщиков, работающих полный день, и, наверное, все разработчики мечтают, что можно будет нажать большую зеленую кнопку и позволить лаборатории верных роботов сделать всю тяжелую работу по тестированию, тем самым освобождая их самих для более возвышенных занятий, как, например, сетевые компьютерные игры. Не смотря на это, если бы достигли этого Шангри-Ла, мы все равно должны были бы продолжать действовать с осторожностью.

Эта статья является критическим анализом «скриптового и проигрывательного» стиля автоматизации регрессионного тестирования приложений с графическим интерфейсом.    

RSS-материал
© 2009-2010 Портал для автоматизаторов тестирования ПО
Автор проекта Поляруш Михаил | При использовании материалов ссылка на www.automated-testing.info обязательна.
Все замечания и пожелания присылайте на webmaster@automated-testing.info.
Яндекс.Метрика