понедельник, 27 июля 2009 г.

Программная ошибка как артефакт существующей и правильной спецификации

Всю свою сознательную профессиональную жизнь я пытался создавать идеальные документы. Даже если это были просто отписки о проделанной ненужной работе. Сначала меня этому учили, потом я стал испытывать от этого удовольствие. Перейдя в QA идея идеальности была похоронена реальностью производства ПО.

Спецификации, технические задания, планы проектов быстро и безвозвратно устаревают. Редкий менеджер (в моей памяти) ведет историю документа и только QA, как мячик скачет от спецификации к менеджеру, от менеджера к разработчику, от разработчика к программе, что бы собрать крупицы правды. По этому же поводу Сем Канер отозвался очередной цитатой недели:

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

А если спецификации нет или она неправильна? - Скачите Шура, скачите.

среда, 22 июля 2009 г.

Паттерны тестирования: Condition\Time waiters

Количество велосипедов растет. Это радует.

Долгое время (ну, как долгое - месяца полтора) мучился, пытаясь сделать тесты Selenium-а более стабильными и не зависимыми от задержек AJAX. В конце концов наделал кучу TimeWaiter - ов. Хотел даже заметку написать. Похвалиться. Типа очередной велосипед готов. Но удачно наткнулся на более фундаментальный труд ;) Решил что данный труд претендует на более продвинутый паттерн.

Имя паттерна: Condition waiter
Назначение паттерна: Разработка автоматизированных тестов ориентированных на изменение состояний объекта.

Перепечатывать не буду - дам ссылку: http://blog.vitorg.ru/webtesting/2009/07/14/selenium-ojidanie-zaversheniya-ajax

понедельник, 20 июля 2009 г.

Цитата недели от Сема Канера: ценность плана тестирования

Ценности в жизни QA - это вообще отдельная ветка размышлизмов. Но сегодня будем цитировать мудрых. Например Сема Канера. У одного их столпов QA выявление ценностей звучит с легким бюрократическим уклоном:

Ценность плана тестирования определяется тем, насколько он помогает в организации процесса тестирования и поиске ошибок. Любые его составляющие, не отвечающие этим задачам, являются пустой тратой времени.
Сем Канер и др.
Тестирование Программного Обеспечения

среда, 15 июля 2009 г.

Паттерны тестирования. Timestamped Name

Я уже упоминал про желание складировать полезные мысли о проектировании автоматизированных тестов - паттернах и стратегиях тестирования. Данная запись одна из, надеюсь, многих и связана с использованием времени - как одного из вспомогательных факторов при создании объектов в процессе тестирования.

Timestamped Names

Имя паттерна: Timestamped Names
Назначение паттерна: Создание уникального имени для объекта

Во время прогона тестов, часто возникает ситуация когда необходимо создать новый объект. У любого объекта есть, как минимум, две характеристики: уникальный идентификатор и имя. Уточним, что имя должно быть более или менее понятным после прочтения (Good, Project etc), т.е. изначально все таки задается текстовая константа, по которой объект и будет именоваться.

У нас есть несколько путей задания задания константы:
- hardcoded константа,
- константа в конфигурационном файле.

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

Случается, что имя объекта также должно быть еще и уникальным. И тут указание имен в конфигурационные файлы выносить проблематично. Создаваться может несколько объектов одного типа, но требуются разные имена. Создавать для каждого объекта отдельную константу - слишком сложно (например имена для 1000 объектов). Нужен smart dynamic name. В данном случае - добавление временного префикса или постфикса к имени объекта. Само имя может как задаваться hardcoded, так и храниться во временном файле.

Например мы создаем товар Goods и и после выполнения timestamped операции получаем имя Goods_<...>, где <...> - это timestamped индекс. В будущем если мы захотим найти товар, с вероятностью 99,99999 мы найдем по данному имени только один товар. Оставшийся 0,00...1% я оставляю на проблемы с потоками, из за которых могут возникнуть два товара с одинаковым именем. Эта проблема известна и решаема, в каждом языке программирования - по своему.

В качестве альтернативы Timestamped Names можно использовать Indexed Name. Данный паттерн к имени создаваемого объекта добавляет числовой префиск или постфикс, который после именования очередного объекта увеличивается на единицу или на определенный шаг.

вторник, 14 июля 2009 г.

Измените свой календарь






Измените свой календарь






Сколько себя помню работающим - я постоянно пытаюсь разобраться со своим time-management.

И когда был системным администратором, и когда стал программистом, и когда стал QA - все время приходилось менять свой календарь. Мне казалось, что это не правильно. Думалось мне - кем бы ты не работал, у тебя должен быть один шаблон календаря, и легкие изменения в формулировках и времени. Мне казалось плохо то, что я постоянно меняю средства планирования - то в электронной таблице, то используя какую нибудь программу, то использование других и нескольких программ. Все время изменялось мое желание - как планировать, как записать, куда записать... А в этом месяце я прочитал книгу "Выживают только параноики" Эндрю Гроува. И наткнулся на цитату, которую хочу поместить в свой недельный цитатник.

Стратегические изменения не начинаются сверху. Они начинаются с вашего календаря.
Эндрю Глоув. Выживают только параноики

Прочитал и задумался (со мной такое часто бывает).

Вспоминая то как менялись моя работа, мои обязанности, мои навыки - я понял, что на самом то деле я пытался приспособиться к новым стратегическим изменениям. И не боролся с изменениями, а использовал свои мозги чтобы к ним приспособиться. В общем то, делал правильно. Бывает радостно понимать, что что-то в этой жизни ты делал правильно.

Кстати. Я меняю работу. А началось все со смены календаря три месяца назад и пересмотра моих профессиональных планов на будущие два года.

понедельник, 6 июля 2009 г.

Имейте бесконечное терпение

Цитата на этой неделе выбрана не случайно (и когда я что то случайно делал? - ведь все с умыслом). Каждому QA случается сталкиваться с одной из следующих ситуаций:
- вам дали сроку "недели хватит", а тестировать нужно "ой как много то";
- самый-умный-программист-в-конторе (а они все такие, забывать об этом не стоит), не желает с вами беседовать о том, что в его фиче есть баги;
- документация "еще в разработке", но тестировать "нужно было уже вчера начинать"...

Цитата нашлась в выписке из правил поведения руководящих работников GE, 30-е годы 20 века. Полностью выписку можно найти здесь: http://www.it4business.ru/up/1913/

Правило № 4: Имей бесконечное терпение

Что тут еще добавишь? Удачной недели. И да прибудет с вами сила... и Терпение.

пятница, 3 июля 2009 г.

Тестеров никто не любит

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


О любви...

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

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

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

Правила Если...

Если ты нашел чужую ошибку - радуйся. Это повод доказать разработчикам, что они бездарные.

Если разработчик говорит, что найденное непонятство это фича - обзови это багом и запости.

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

Если ты еще не нашел багу - значит ты пока проявил великодушие и просто даешь передышку этим несносным разработчикам.

Правила Будь...

Будь недоверчивым. Не верь никому - потому, что зачем кому то верить, если тебе платят за обратное?

Будь нудным - потому, что нудных не любят. Ты тестер - тебя не могу любить по определению, так что ты ничего не теряешь.

Будь недовольным - потому, что недовольных не трогают, а стараются им угодить.

Будь злым - потому, что злых бояться, а поскольку тебя никто не любит, то пусть хотя бы бояться.

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

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


Удачного рабочего дня, трудяги !

понедельник, 29 июня 2009 г.

Цитата недели для QA от Developer

Цитата недели для QA от Developer

Новая цитата недели пришла не от QA и не для QA, но данная фраза может быть перефразирована для специалиста любой специальности и любого направления. В том числе и QA:

Программист каждый день должен узнавать что-то новое. Если он этого не делает, значит он живет во вред себе
Джеймс Гослинг (автор языка программирования Java)

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

Кроме цитирования на собеседованиях, я еще и пытаюсь жить так, как это звучит: новая статья, новая страница в книге, новый паттерн проектирования, новый баг, новое понимание того как писать testcase, новый...новая...новое...новые...

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

понедельник, 22 июня 2009 г.

Паттерны тестирования. Велосипед первый: GUI-Domain-Test-Report


Паттерны тестирования.
Велосипед первый: GUI-Domain-
Test-Report




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

И поскольку я человек умный, я должен как и всякий умный человек размышлять об умных вещах (подозреваю, что за такие предложения нужно сжигать прилюдно). Я уже упоминал про желание складировать паттерны тестирования в своем блоге . В данной заметке я бы хотел обсудить паттерн построения архитектуры тестовых фреймворков приложений, которому я дал название "GUI-Domain-Test-Report".

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

Проблематика построения тестовых фрейморков приложений

WebDriver: Design Patterns and Development Strategies

Первая ссылка это Design Patterns and Development Strategies . Проект WebDriver должен быть знаком тем, кто занимается автоматизированным тестированим веб-приложений. В документации к данному проекту присутствует описание стратегий-паттернов тестирования.

Остановим внимание на двух:
- DomainDrivenDesign - стратегия, которая предлагает, что работать с веб-приложением ннеобходимо на уровне предметной области (обсудим позже, что такое предметная область приложения).
- PageObjects - стратегия, которая предполагает, что должны быть выделены объекты ответственные за работу со страницами, с которыми вам необходимо работать (обсудим так же позже и подробнее).

GUI-level

В статье компании ATSG упоминаются оконные объекты:
Оконные объекты - этот тип компонентов специфичен для автоматизированного тестирования, в частности GUI-level тестирования и один из наиболее критичных к изменениям тестируемого приложения. Поэтому, для тестирования подобных компонент следует выработать некоторый workflow-сценарий, который затронет все ( или хотя бы просто большинство ) оконных объектов

В статье используется термин GUI-level, которым очень и очень важен для нашего исследовния. Level означает, что существует распределенная архитектура с ярко (или темно) выраженными уровнями-слоями. Вспоминая DomainDrivenDesign (упомянутый ранее), можно выделить также и Domain уровень - уровень предметной области.

Test-Buisiness-GUI

Недавно прошла конференция SQADAYS 2009, на которой мне не удалось побывать. Среди прочих презентаций нам будет очень очень полезна презентация господина Ревко Практические Рекомендации По Организации и Проведению Автоматизированного Тестирования. На странице 11 данной презентации появляется картинка с иерархией различных уровней.






"Для создания тестов, тестируемое приложение нужно разбить на 3 основных уровня:
- Тестовый Уровень
- Бизнес Уровень
- GUI Уровень
2 дополнительных:
- Уровень данных

- Уровень Функций"


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

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

Фреймворк-тест-драйвер-приложение

В веб-семинаре Алексея Баранцева Автоматизация функционального тестирования приводился пример стека автотестов:

И один из примеров стека автотестов:

В том числе на семинаре были озвучены паттерны тест-дизайна:
- адаптер для всего приложения,
- адаптеры страниц,
- адаптеры частей страниц\блоков,
- репозитарий элементов UI.

Замечание: Алексей просил не выкладывать материалы семинара на общее обозрение, - чего я и не делаю, но делаю небольшую рекламу его презентации и пиарю его курсы - надеюсь мы в расчете ;).

Нам важны данные материалы поскольку на конкретном примере TestNG-Tests-Selenium-Application мы можем понять, как приложение разбивается на слои с использованием существующих продуктов.

Краткое подведение итогов
Собственно, это все материалы, на которых я пытаюсь обосновать свое видение паттерна построения архитектуры тестового фреймворка приложения.

Вполне очевидно что перед нами вырисовывается проблема проектирования тестового фреймворка приложения. Мы видим, что тему построения тестового фреймворка приложения затронута в разных местах, и затронута в одном ключе - разделение архитектуры на слои, отделение мух от котлет, прошу прощения, - GUI от тестов.

GUI-Domain-Test-Report (GDTR)

Как это принято в умных книгах, я приведу краткое описание паттерна:

Наименование: GUI-Domain-Test-Report (GDTR)
Также известен: стратегия построения тестового фреймворка
Тип: системный
Уровень: архитектурный
Назначение: обеспечить создание тестового фреймворка разрабатываемого приложения

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

Паттерн GUI-Domain-Test-Report или в дальнейшем GDTR я бы определил как архитектурный, по той причине, что он связан с построением архитектуры тестового фреймворка приложения.

Еще раз о том, что я вкладываю в термин тестовый фреймворк приложения - это приложение, разработанное для тестирования какого-либо бизнес приложения (или просто приложения).

Паттерн ADTR подразумевает выделение логически разделенных слоев в тестовом фреймворке приложения для обеспечения более гибкой архитектуры. Паттерн включает выделение тех же самых уровней что и в презентации Ревко , но
+ еще один, самый верхний, следующий после тестового - слой формирования отчетности ADTR:REPORT
- один, уровень Функций, который я не понимаю для чего выделять.
- еще один уровень Данных - о котором позже.

GDTR: GUI-ADAPTER
Данный слой предоставляет набор объектов (GUI-ADAPTERS) , озвученных ранее как ObjectAdapter или оконные объекты.

В основе создания данных объектов как я понимаю, лежит использование паттерна проектирования Adapter (он же Wrapper) (http://en.wikipedia.org/wiki/Wrapper_pattern). Любой графический объект (элемент оконной формы) может иметь свой т.н. адаптер для манипуляции с его содержимым в самом тестовом фреймворке.

Я бы выделил следующие графические объекты:
- Элемент (может быть объединен с другими элементами в контейнере формы или более высокого уровня).
В качестве примера графического объекта можно привести: выпадающий список, поле ввода, чекбокс или радиокнопка.

- Форма (может быть объединена с другими формами в общий компонент или страницу).
В качестве примера: вкладка с зависимыми элементами, тег FORM в HTML.

- Общий компонент (является контейнером для обычных полей и форм, но может быть помещен в контейнер страницы), в качестве примера могу назвать виджеты DoJo (компонент для выбора даты).

- Страница (является контейнером обычных полей, форм, общих компонент) .

Хочу заметить, что я допускаю возможное перемешивание контейнеров: появление общих компонент в формах, страниц в общих компонентах.

Что же входит в обязанности адаптера графических объектов:
- получение данных,
- установка данных,
- клики,
- проверки данных и пр.

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

О том как разделять локаторы для различных операций я собираюсь обсудить отдельный паттерн в отдельной заметке.

В качестве примера, для чего может быть создан графический адаптер - можно упомянуть адаптер формы авторизации на сайте. Данная форма может размещаться в нескольких местах на сайте: например на центральной странице и на отдельной странице. Форма включает в себя два поля (логин и пароль) и кнопку подтверждения авторизации. Соответственно можно выделить адаптер формы авторизации и два адаптера страниц на которых располагается данная форма.

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

GDTR: DOMAIN-ADAPTER
Данный слой предназначен для того, что бы "беседовать" с приложением на его языке - на языке проблемной области. В этом слое также создаются адаптеры, но уже над графическими адаптерами и для бизнес логики.

В качестве примера можно привести оформление товара в интернет магазине. Для выполнения заказа мы должны:
1. Авторизоваться (адаптер авторизации);
2. Перейти в каталог (адаптер главного меню, адаптер страницы каталога);
3. Перейти выбрать товар (скорее всего адаптер формы товара с ссылкой на товар);
4. Перейти на страницу корзины (адаптер страницы корзины);
5. Оформить заказ (адаптер страницы оформления заказа).

В скобках я указал приблизительные gui-adapter-ы для выполнения операции заказа товара. Данную операцию из 5 шагов может выполнять даже один domain adapter.

Здесь возникает вопрос - могут ли одни адаптеры проблемной области включать другие адаптеры проблемной области? Я считаю, что могут. В противном случае возникает дублирование кода. При усложнении поведения сайта, я бы рассмотрел возможность выделения в отдельный адаптер проблемной области шаги 2 и 3 и еще в один отдельный адаптер шаги 4 и 5. Но тут нужно думать ;)

GDTR: TEST

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

Я бы назвал данный уровень модульным тестированием результатов работы адаптеров более низких уровней. Тестовые объекты проверяют и отваливаются с ошибкой, либо отрабатывают успешно. О модульном тестировании, использовании тестовых фреймворков, думаю, в данной заметке особо распространяться не стоит.

В качестве примера можно привести оформление заказа товара, с последующей проверкой - отразилась ли информация о товаре (количество и сумма) на странице "Корзина".

GDTR: REPORT
Я выделил данный уровень в отдельный, поскольку получение отчетов о тестах, как мне кажется, должно быть выделено из уровня тестов. Сделать это необходимо хотя бы потому, что отчеты могут быть представлены в разных форматах, с разной детализацией содержать разные данные - т.е. быть вообще разными.

На практике тестовый уровень и уровень формирования отчетов о проведенных тестах могут встречаться в одном фреймворке (например TestNG формирует отчетность в HTML формате, зеленым цветом выделяются прошедшие тесты, красным - не прошедшие.)


Заключение
Надеюсь, что в моей заметке есть и новое и занятное, (да бог чтобы не было такой ситуации когда новое не занятное, занятное не новое) и даже неправильное. К сожалению я не присутствовал на SQADays 2009 и не знаю как обсуждалась презентация господина Ревко. Очень бы хотелось, но не получилось. Думаю результаты обсуждения могли бы серьезно повлиять на содержание данной заметки.

Конечно же многое еще не раскрыто. Есть еще вопросы, которые следует обдумать:
- Вопросы именования объектов слоев. Весьма спорный вопрос. Например, именовать все тестовые объекты начиная с префикса Test. Я лично против такой обязательности. Но в JUnit так принято (а вот в TestNG - нет).

- Проблема разделения данных между слоями. В презентации господина Ревко есть слой, Данных, растянутый между центральными. Я пока не готов рассуждать, как его разделить между упомянутыми мной слоями паттерна GDTR.

- Проблема отделения локаторов графических элементов от их поведения - в литературе используется термин GUI mapping. Я упомянул проблему в заметке. Дай бог разумения понять, как это делается.

Надеюсь, что замечания по паттерну скоро поступят, и я подправлю данную заметку.

Замечания принимаются и обсуждаются.

воскресенье, 21 июня 2009 г.

Цитата недели: Хороший тестировшик, не тот, кто выявит больше всего ошибок, и не тот, кто заставит смутиться даже самого первоклассного программиста. Лучшим является тот, кто добьется исправления наибольшего количества ошибок. Сэм Канер

Умная мысль для цитирования на этой неделе:

Хороший тестировшик, не тот, кто выявит больше всего ошибок, и не тот, кто заставит смутиться даже самого первоклассного программиста. Лучшим является тот, кто добьется исправления наибольшего количества ошибок.
Сэм Канер "Тестирование ПО"