вторник, 12 мая 2009 г.

QTP: Реализация GUI слоя при помощи классов



Автор: Meir Bar-Tal
Перевод: Сергей Талалаев (SQAdotBY)
Оригинальная статья: Implementing a GUI Layer with Classes


В продолжении темы сотрудничества с уважаемым ресурсом AdvancedQTP.com и с любезного разрешения автора, хотел бы представить перевод очень интересной статьи с данного сайта.

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


Аннотация

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


Введение

Основная проблема в автоматизированном тестировании – это как уменьшить издержки по поддержке скриптов. Вопросы вида: “Должны ли мы использовать объектный репозиторий (Object Repository OR) или дескрипторное программирование (Descriptive Programming DP)? Если выбран OR, то должны ли мы использовать общий OR или локальный для каждого Action? Если выбран DP, тогда какой оптимальный вариант его реализации?” достаточно повсеместны и ответы на них могут зависеть как от конкретных особенностей проекта так, во многих случаях, и от людей, вовлеченных в процесс.

В этой статье я проанализирую концепцию Тестовых Объектов (Test Objects) в рамках принципов OO (Object Oriented). Я попытаюсь показать, что реализация объектного репозитория в QTP не соответствует этим принципам, и каково влияние этого факта на разработку автоматизированных тестов с точки зрения эффективности затрат и трудоемкости поддержки. Затем я опишу расширение OR-концепции, которое соответствует принципам OO – GUI слой (GUI Layer). Эта концепция была адаптирована экспертами компании SOLMAR, основываясь на том факте, что возможно максимизировать повторное использование кода (и таким образом улучшить поддерживаемость кода) используя OO подход, согласно которому автоматизируемый проект разбивается на несколько уровней абстракции.


Тестовые Объекты и Run-Time Объекты

Тестовый объект содержит в себе ссылку на run-time объект – объект реального мира, который инициирован в тестовом приложении. Тестовый объект содержит описание объекта, на который он ссылается, в виде набора атрибутов и значений служащих критерием для поиска нужного объекта в ходе тестового прогона. Это описание больше всего похоже на то, что вы себе представляете, идя на встречу с незнакомкой (“Я брюнетка, стройная и высокая, и буду одета в красное платье и туфли”)

Аналогично QTP использует описание для запроса к OS, загружен ли в настоящий момент объект в оперативную память. Если ответ положительный, то OS вернет адрес объекта (ссылку или указатель) и, следовательно, QTP получит доступ к публичным методам и свойствам объекта, в то время как частные методы и свойства остаются скрытыми от просмотра по определению (таким образом QTP никогда не вмешивается в частную область, чего вы бы хотели в отношении брюнетки, если повезет!)

Хотя это описание может быть слишком упрощено, но по существу это такой процесс, который позволяет нам взаимодействовать с GUI (и другими) объектами используя QTP или другое средство автоматизации (Test Partner, Test Complete, Rational Robot, AutoIt и т.д.) Более детальное объяснение различия между Тестовыми Объектами и Run-Time Объектами доступно в статье Yaron Assa "Differences and Connections between Runtime Objects and Test Objects" (2009).


Тестовые Объекты и Объектный Репозиторий

Рассказанное выше естественно заставляет нас думать о тестовых объектах как о данных. Что я имею в виду? Основываясь на описании, построенном из свойств и значений, QTP имеет возможность распознать GUI объект среди всех объектов, загруженных в данный момент в машинную память. Этот процесс подобен тому, как мы получаем необходимую запись из БД согласно условию WHERE в SQL запросе. Разница лишь в том, что в данном случае OS (Windows), а не БД возвращает запись. Кроме того, запись содержит только одно поле – ссылку на реальный run-time объект. Следуя данной мысли, это кажется вполне естественным хранить эти записи - тестовые объекты (Test Objects) – в базе данных, которой собственно Объектный Pепозиторий (Object Repository) и является (если вы обратили внимание на файлы с расширением bdb в QTP тестах, то знайте, что bdb в действительности означает Berkeley Data Base – продукт компании Oracle).

В чем же собственно проблема с подходом, использующим OR? Тестовые объекты в действительности являются данными, но мы до текущего момента вынуждены выполнять действия с Run-time объектами, что, учитывая вышесказанное, предоставляет нам искаженную картину. Ниже я объясню почему.

Это действительно, правда, что OR, при правильном использовании, предоставляет наилучшую технику, в соответствии с которой нам необходимо сохранить описание каждого GUI объекта всего лишь раз для уменьшения стоимости изменений. Тем не менее, чтобы достичь этого должны быть потрачены большие усилия на правильное управление тестовым проектом, потому что непродуманные запросы и недостаток ресурсов могут привести нарушению целостности этого ценного ресурса (OR). Например, предположим, что два инженера автоматизации работают одновременно с общим репозиторием, но один из них модифицирует скрипт для прошлой версии приложения, а другой – для новой. При условии, что GUI изменения выполняются регулярно от одной версии приложения к другой, не придется долго ждать, пока репозиторий окажется заполненным новыми лишними объектами необходимыми для работы с новой версией приложения. И это еще относительно неплохой результат. Гораздо более худший результат вы получите в случае, если каждый инженер изменяет набор свойств существующих объектов для отражения своих требований, безвозвратно разрушая ROI (возврат инвестиций) проекта автоматизации в целом. Конечно имеются решения и для таких ситуаций, такие как хранение отдельных версий репозитория для соответствующей версии приложения и использование специального ПО по управлению конфигурациями в рамках проекта автоматизации. Но, как говорилось ранее, это требует хорошего управления проектом, что не всегда доступно.

Кроме того поддержка версионности объектного репозитория оставляет открытой одну проблему. По причине того, что автоматические тесты являются регрессионными по своей сути, их модификация затрагивает не только OR, но также и код, который реализует непосредственные манипуляции с GUI объектами и проверки, также как и работу с входными данными и ожидаемым результатом. В общем случае, когда при переходе от одной версии приложения к другой меняются только описания объектов, использование объектного репозитория действительно будет оправданным. Тем не менее, чаще ситуация обратная, изменения в GUI отражают изменения в функциональности приложения, которые в свою очередь гораздо чаще сопровождаются более глубокими изменениями – на уровне БД, например. Таким образом, изменения в GUI требуют изменений как на уровне объектного репозитория, так и на уровне скрипта, который ссылается на тестовые объекты и плюс к этому на уровне входных данных для самого скрипта. Учитывая то факт, что скрипты чаще всего подвергаются модификации, а не разработке, вышеупомянутый анализ приводит меня к мысли, что нечто в концепции OR неправильно по отношении к управлению крупномасштабными проектами автоматизации.


Объектно-ориентированный взгляд

Концепция ООП базируется на трех основных принципах – инкапсуляции, наследовании и полиморфизме. Инкапсуляция означает упаковку вместе функциональности и данных, которые сосуществуют вместе и данная упаковка, через которую осуществляются обращения, называется классом. Фактически классы – это представление данных (например, Customer, Product и т.д.) Различие между полнофункциональным классом и обычной структурой данных в том, что класс содержит в себе функции по работе со своими данными - полями. Эти функции обычно называются методами класса. Например, типичный класс для Customer-а включал бы себя следующие поля, которые однозначно определяют покупателя (customerId, firstName, lastName, phoneNo и т.д.) вместе с методами setCustomerId, getCustomerId, которые присваивают и возвращают значения соответствующим полям, также как и getCustomerAge and getCustomerBalance выполняющими расчеты на основе текущих значений полей и возвращающие результат.

Наследование тесно связано с одной из важнейших целей ОО подхода – повторного использование кода. В объектно-ориентированных языках, таких как C++ и Java, повторное использование кода вступает в игру посредством возможности создавать новый класс, который “наследует” поля и методы уже созданного класса (называемого базовым классом) и расширяет их согласно специфическим требованиям, поставленным для нового класса.

Полиморфизм – это еще один мощный принцип, который делает возможным определять несколько версий одной функции (с одним именем, но с различным набором аргументов) для того чтобы прозрачно реагировать на различные ситуации в рамках контекста приложения. Например, у нас есть необходимость производить одну и ту же операцию с различным набором аргументов (float, int) и тогда вместо того, чтобы в одной функции реализовывать набор условных операторов для проверки типов переданных параметров, мы определим несколько функций с одинаковым именем, но с разной сигнатурой (различным набором аргументов). Следовательно, в нашем коде, использующем эти функции, нам не придется использовать приведение типов; мы будем использовать одинаковый интерфейс в обоих случаях, полагаясь на то, что корректный вызов будет осуществлен самой средой выполнения. Тем не менее, в QTP две последние концепции (наследование и полиморфизм) не могут быть реализованы в рамках VB скрипта, который обеспечивает только ограниченную поддержку работы с классами. Тем не менее, позже мы увидим, что это не причина отказываться от использования классов в автоматизации тестирования.

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

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


Автоматизация Тестирования и Разработка ПО

Я был свидетелем одной вещи на протяжении всей моей карьеры – это то, что QA профессионалы всех уровней рассматривают автоматизацию тестирования лишь как особый вид тестовой деятельности. Не удивительно, что не так уж редко можно встретить профессионалов в автоматизации, думающих также о роли автоматизации. Иногда это даже отражается в названии должностей для персонала автоматизации: “авто-тестер” - это одно из абсурдных названий из тех, что я встретил несколько лет назад. Все это отражает непонимание роли Инженера Автоматизации и, как я объясню в дальнейшем, данное мнение действительно не соответствует сущности автоматизации тестирования.

Задача автоматизации тестирования не должна рассматриваться иначе, чем любая другая контекстно-зависимая задача автоматизации. Вообще говоря, компьютерная программа, которая выполняет набор операций вместо человека – реализует автоматизацию. Таким образом, любой блок кода по сути можно рассматривать как автоматическое устройство или робота. Скрипты, которые производят операции над GUI объектами (как тесты в QTP) не отличаются от других частей ПО. Говоря другими словами, проект тестовой автоматизации, несомненно, является специфичным видом проекта по разработке ПО. И как любой программный продукт проект автоматизации также имеет свой собственный документ с функциональными требованиями (Software Requirements Specifications) и дизайн (Software Test Design) документ (либо тест дизайн в одном из промышленных фреймворков, например HP’s Quality Center или Orcanos’ QPack), которыми должен руководствоваться инженер автоматизации при реализации требуемого кода.

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

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

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

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


Следуя описанному выше, я думаю, мы можем заключить, что проект автоматизации определенно должен управляться также как проект разработки. Если это так, почему кто-то должен снова и снова становиться жертвой заблуждения о проекте автоматизации как о тривиальной задаче (методика ”записи-воспроизведения” ничего не напоминает?) в то время как верно обратное? Почему бы тогда не использовать широко применяемый при разработке подход – Объектно Ориентированное Программирование – чтобы достичь наилучших результатов? Далее я опишу методику реализации автоматизированных скриптов, основанную на расширении концепции OR ( GUI слой ) и базирующую на твердых принципах ООП.


Концепция слоев

Я надеюсь, что объяснил достаточно подробно, почему подход с использованием Объектного Репозитория (OR), повсеместно используемый в скриптах, далек от оптимального. Теперь, продолжая начатое обсуждение, позвольте взглянуть на концепцию разработки кода, разделенного на слои или собственно концепцию GUI слоя. Вообще, слои весьма полезны для максимизации повторного использования кода (возвращаясь к предыдущему обсуждению принципов ООП). Я бы определил GUI слой как множество классов, которые объединяют (инкапсулируют) вместе необходимые интерфейсы для манипуляции GUI объектами тестового приложения для выделенной функционально части. Другими словами – это множество классов, обеспечивающих связь между GUI тестового приложения (то есть определенных тестовых объектов) и Бизнес или Прикладным Слоем, о котором мы поговорим позднее. Может быть, было бы более подходящим назвать его Слой GUI-Бизнес Адаптера, но среди экспертов уже устоялся термин GUI Слой, для краткости. Я проиллюстрирую ниже, как такой слой может быть создан и, какие преимущества достигаются при применении данного подхода в рамках тестовой автоматизации.

Реализация GUI Слоя

Инкапсуляция Тестовых Объектов в Классы

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

Class Login

End Class

Class MainWindow

End Class

Class CreateCustomer

End Class

и так далее для каждого контекста приложения. По причине того, что QTP не позволяет прямое создание класса определенного во внешней библиотеке с помощью оператора New, нам также необходимо определить следующую функцию (разновидность конструктора), которая вернет нам экземпляр GUI-слоя:

'——————————————————————————-
Public Function CreateLogin()
'——————————————————————————-
'Function: CreateLogin
'Creates an instance of the Login class
'
'Remarks:
'
'Arguments:
' N/A
'
'Returns:
' Object - As Login
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

Dim objLogin

Set objLogin = New Login

Set CreateLogin = objLogin
'——————————————————————————-
End Function
'——————————————————————————-

Второй шаг, очевидно, определить список элементов внутри каждого класса. Теперь, так как каждый класс, согласно вышеизложенному – это контейнер других GUI объектов, мы будем использовать Scripting.Dictionary для хранения ссылок на тест-объекты находящиеся на окне, диалоге или странице. (объект Dictionary широко обсуждался в статьях опубликованных в AdvancedQTP’s базе знаний). Таким образом, первый элемент который я представлю здесь, будет общим для всех GUI Layer классов, и я определю его как m_htChildObjects:

Class Login
Private m_htChildObjects 'As Scripting.Dictionary

End Class

Class MainWindow
Private m_htChildObjects 'As Scripting.Dictionary

End Class

и так далее для каждого контекста приложения (ht – префикс для HashTable, чем объект Dictionary на самом деле и является). Частный элемент m_htChildObjects будет доступен через свойство класса ChildObjects. Это свойство определено как:

'——————————————————————————-
'Property: ChildObjects
'Get and Set the m_htChildObjects member field
'
'Remarks:
' R/W
'
'Arguments:
' dic
'
'Returns:
' m_htChildObjects As HashTable
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

Public Property Get ChildObjects()
'——————————————————————————-
Set ChildObjects = m_htChildObjects
'——————————————————————————-
End Property
'——————————————————————————-

'——————————————————————————-
Public Property Let ChildObjects(ByRef dic)
'——————————————————————————-
Set m_htChildObjects = dic
'——————————————————————————-
End Property
'——————————————————————————-

Третий шаг – определение всех объектов внутри каждого контекста. Для этой цели я определю публичный метод Init:

'——————————————————————————-
Public Function Init()
'——————————————————————————-
'Function: Init
'Initializes the context and child objects
'
'Dependencies:
' IsContextLoaded(htContext)
'
'Remarks:
' N/A
'
'Arguments:
' N/A
'
'Returns:
' True/False
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

ChildObjects = CreateObject("Scripting.Dictionary")

With ChildObjects
.Add "Browser", Browser("name:=My App")
.Add "Page", ChildObjects("Browser").Page("title:=My App \- Login")
.Add "Username", ChildObjects("Page").WebEdit("html id:=Username")
.Add "Password", ChildObjects("Page").WebEdit("html id:=Password")
.Add "Submit", ChildObjects("Page").WebButton("outertext:=Submit")
End With

'IsContextLoaded is a function that iterates through the Dictionary and checks if the GUI objects "exist"
Init = IsContextLoaded(ChildObjects)
'——————————————————————————-
End Function
'——————————————————————————-

Часть кода, показанного выше, описывает типичный метод Init для GUI Layer класса страницы логина в Web приложении. Тестовые объекты добавляются, как элементы словаря ChildObjects и их свойства определены посредством Дескрипторного программирования (DP). Читатель может легко провести аналогию с Объектным репозиторием (OR). Благодаря этому встроенному методу мы можем быть уверены, что GUI-объекты всегда определяются в одном месте. В конце кода метода вы можете отметить, что он возвращает результат вызова функции IsContextLoaded которая принимает в качестве аргумента словарь, содержащий ChildObjects.
IsContextLoaded определятся в отдельной общей библиотеке, следующим образом:

'——————————————————————————-
Public Function IsContextLoaded(ByRef htContext)
'——————————————————————————-
'Function: IsContextLoaded
'Checks that the current GUI context is loaded
'
'Iterates through the htContext (HashTable) items and executes the Exist method with 0 (zero) as parameter.
'
'Remarks:
' N/A
'
'Arguments:
' ByRef htContext - As HashTable
'
'Returns:
' True/False
'
'Owner:
' Meir Bar-Tal, SOLMAR Knowledge Networks Ltd.
'
'Date:
' 11-Nov-2008
'
'See Also:
'
'——————————————————————————-

Dim ix, items, keys, strDetails, strAdditionalRemarks

'—————————————————————————
items = htContext.Items
keys = htContext.Keys

For ix = 0 To htContext.Count-1
IsContextLoaded = IsContextLoaded And items(ix).Exist(0)
strDetails = strDetails & vbNewLine & "Object #" & ix+1 & ": '" & keys(ix) & "' was"
If IsContextLoaded Then
intStatus = micPass
strDetails = strDetails & ""
strAdditionalRemarks = ""
Else
intStatus = micWarning
strDetails = strDetails & " not"
strAdditionalRemarks = " Please check the object properties."
End If
strDetails = strDetails & " found." & strAdditionalRemarks
Next
'—————————————————————————

Reporter.ReportEvent intStatus, "IsContextLoaded", strDetails
'——————————————————————————-
End Function
'——————————————————————————-

И она возвращает Истину если все объекты, определенные в словаре идентифицированы или Ложь если хотя бы один из объектов не найден. Эта функция универсальная и используется для всех проектов, которые я веду для того чтобы быть уверенным, что QTP не зависнет при попытке выполнения операций с несуществующим GUI-объектом. Еще одно преимущество этого метода в том, что он указывает точно на тот объект, который вы хотите проверить и изменить, делая поддержку значительно более легкой.


Инкапсуляция бизнес методов в классы

Следующий шаг, после определения дочерних объектов для тестируемого контента – это определение операций, необходимых для выполнения бизнес-сценариев в рамках данного контента. Это легко реализуется через методы класса. Например, класс Login, описанный выше нуждается в следующих методах для начала работы с ним: SetUsername, SetPassword и Submit. Они показаны ниже:

'——————————————————————————-
Public Function SetUsername()
'——————————————————————————-
'Function: SetUsername
'Set the Username field
'
'Dependencies:
' N/A
'
'Remarks:
' N/A
'
'Arguments:
' N/A
'
'Returns:
' N/A
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

ChildObjects("Username").Set GlobalDictionary("Username")
'——————————————————————————-
End Function
'——————————————————————————-

'——————————————————————————-
Public Function SetPassword()
'——————————————————————————-
'Function: SetPassword
'Set the Password field
'
'Dependencies:
' N/A
'
'Remarks:
' N/A
'
'Arguments:
' N/A
'
'Returns:
' N/A
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

ChildObjects("Password").Set GlobalDictionary("Password")
'——————————————————————————-
End Function
'——————————————————————————-

'——————————————————————————-
Public Function Submit()
'——————————————————————————-
'Function: Submit
'Presses the Submit button
'
'Dependencies:
' N/A
'
'Remarks:
' N/A
'
'Arguments:
' N/A
'
'Returns:
' N/A
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

ChildObjects("Submit").Click

'TODO: Verify data submission performed successfully
'——————————————————————————-

End Function
'——————————————————————————-

Отметим использование GlobalDictionary для получения требуемых значений для функций (username, password) и использование свойства ChildObjects для получения через тестовый объект ссылки на выполняемый объект.

Следующим шагом будет перемещение на Бизнес Слой (Business Layer), который реализует бизнес сценарий, построенный на базе GUI Слоя (GUI Layer). Например, для того чтобы выполнить логин в систему на основе вышеописанного примера мы реализуем следующую функцию:

'——————————————————————————-
Public Function do_login()
'——————————————————————————-
'Function: do_login
'Implements the business logic of the do_login Action.
'
'Remarks:
'
'Arguments:
' None
'
'Returns:
' Status
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

Dim intStatus, objLogin

Set objLogin = CreateLogin()
If objLogin.Init() Then
objLogin.SetUsername()
objLogin.SetPassword()
objLogin.Submit()

'If login succeeds
intStatus = micPass
Else
intStatus = micFail
End If

do_login = intStatus
'——————————————————————————-
End Function
'——————————————————————————-

Отметим использование класса Login описанного выше и его функции Init как меру предосторожности для уверенности, что необходимый контент загружен и не завис, как обсуждалось ранее. Как вы можете видеть, код вышеописанной функции достаточно просто для понимания, и не перегружен ссылками на OR объекты, источники данных как при обычной реализации. Если изменения на GUI затронут объекты в данном контенте – все изменения будут сконцентрированы только в данном пакете, как те что касаются собственно свойств объектов так и механизмов работы с дочерними объектами. Еще одно преимущество данной методики – это стандартизация. Разрабатывая код по данной схеме, мы достигаем высокой степени унификации кода написанного разными разработчиками и таким образом улучшаем управляемость тестового проекта.

Более продвинутая альтернатива последнему примеру – это упаковка таких бизнес-функций, используя Command Wrapper шаблон проектирования, как это описано в моей статье Function Pointers in VB Script (revised). Например:

'VB Script Document
Option Explicit

'——————————————————————————-
Class do_login
'——————————————————————————-
'Class: do_login
'Encapsulates the do_login Action.
'
'Remarks:
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-
'——————————————————————————-
'Methods
'——————————————————————————-
'——————————————————————————-

Public Default Function Run()
'——————————————————————————-
'Function: Run
'Implements the business logic of the do_login Action.
'
'Remarks:
'
'Arguments:
' None
'
'Returns:
' Status
'
'Owner:
' John Doe
'
'Date:
' dd-MMM-yyyy
'
'——————————————————————————-

Dim intStatus

Set objLogin = CreateLogin()
If objLogin.Init() Then
objLogin.SetUsername()
objLogin.SetPassword()
objLogin.Submit()

'If login succeeds
intStatus = micPass
Else
intStatus = micFail
End If

Run = intStatus
'——————————————————————————-
End Function
'——————————————————————————-
'——————————————————————————-

End Class
'——————————————————————————-

Адаптация данной методики делает возможным реализацию продвинутых универсальных контроллеров (generic controller), которые загружают свои сценарии из внешних источников данных, таких как XML файл. Такие управляющие структуры были разработаны мной и моими партнерами в SOLMAR Knowledge Networks как часть нашего универсального фреймворка - Object Oriented comprehensive automation framework - My System.


Выводы


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


Read more...

пятница, 8 мая 2009 г.

Читайте нас в Quality Matters, Issue 2


Немного с опозданием, но хочу поделиться с вами очередной приятной новостью!
Во 2-м выпуске журнала Quality Matters напечатали мою статью по развитию и обучению тестировщиков.
Второй выпуск журнала можно скачать здесь.

Постараемся не останавливаться на достигнутом! ;)
Присоединяйтесь!

Всегда ваша,
Наташа Искорцева (Густыр)
Read more...

четверг, 16 апреля 2009 г.

Разоблачение Excel:
Проверка вводимых данных - выпадающие списки



Часто ли у вас возникало желание, после получения отчета в Excel (абсолютно на любую тематику), убить его автора? Если возникало и не раз – скорее всего вы наш пациент :)






1. Отчёт, отчёт и еще раз …?

Казалось бы чем можно убить любую здравую идею, подразумевающую некоторую информационную составляющую: ”Давайте соберем статистику использования различных операционок на проектах”, “Надо бы собрать сведения об используемом ПО для оптимизации расходов компании” и т.д.?

Правильно – бездарно собранной информацией!!!

Итак, смотрим, что мы получили в ответ на наш запрос:

Раз



И два



С одной стороны вроде и информация собрана, а с другой…

Бухгалтррия Плюс – это почти Бухгалтерия Плюс, но не совсем.
Антиврус (ПО) – это почти Антивирус (ПО), но не совсем.
Отдел сопровждения ПО – это почти Отдел сопровождения ПО, но не совсем.

И уж совсем ни одно и тоже Windows XP, Win XP, XP, WinXP.
Как впрочем и 1C Бухгалтерия, 1C, 1C Бухгалтерия 7.0.

Поэтому, засучив рукава, идем за большим напильником и начинаем … :)

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


2. Очень гибко хорошо, очень гибко плохо?

На вопрос, что же использовать в качестве хранилища нашей кропотливо, но в тоже время очень срочно, собираемой информации ответ настолько очевиден, что иногда вызывает недоумение: ”Вам может еще и базу данных слепить по-быстрому? Возьмите вот Excel и завтра чтобы отчет был у меня на столе.”

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

Все казалось бы верно, но возвращаясь к собранным отчетам, возникает чувство некоторой неполноценности: ”А можно, чтобы все также просто как в Excel, но еще и чтобы контроль данных был?” (перед глазами заботливо всплыл образ Никулина и его ”перламутровые пуговицы”).
И чтобы тоска от сознания необходимости ковырятся в VB for application, макросах, формулах не потушила робкую надежду, как минимум, дочитать эту статью до конца, а как максимум, реализовать то, что в ней написано, сразу ответим – можно и это не так уж сложно, как может показаться на первый взгляд.

Итак, устраиваемся поудобнее и готовимся увидеть необычное и удивительное в привычных и обыденных вещах.


3. Готовим прокрустово ложе.

Для начала нам нужно подготовить корректные значения для заполнения наших выпадающих списков правильными величинами. Это можно сделать на отдельной странице нашего Excel файла, назовем её просто и незатейливо – ”Списки (первый вариант)” и скопируем в нее наш список проектов.



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



И активируем диалог валидации данных ( Main menu>Data>Data Validation ) для выбранной ячейки



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

Первая страница диалога – Settings (в большинстве случаев её оказывается достаточно) позволяет вам ограничить входные данные согласно заданным правилам. Для настройки необходимого нам типа валидации следует выбрать значение выполнить установки согласно картинке ниже, то есть Allow = List.

Обратите внимание,что на странице появились дополнительные элементы управления:
In-cell dropdown – говорит, что значения предлагаются в виде выпадающего списка;
Source – указывает где брать допустимые значения.



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



Более удобный вариант подсказки предполагает использование вкладки Error Alert. При использовании этого варианта сообщения появляются при попытке выхода из поля при условии неправильного введенного значения.



Посмотрим на результат применения всех трех заполненных вкладок:



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

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


3.1. Огласите весь список, пожалуйста.

Оказывается “огласить” список допустимых значений тоже можно не одним способом, а как минимум тремя.

Перечисление списка допустимых значений.
Первый и самый простой (именно этот способ и запечатлен на рисунке выше) – это перечисление списка значений через разделитель ; напрямую в поле Source первой вкладки:



Быстро, понятно, удобно и …
не стоит так делать (точнее делать можно, но предварительно хорошо подумав)

Представим ситуацию, когда таким образом провалидированные поля разбросаны щедрой рукой по всему Excel файлу и вдруг оказывается, что нужно добавить в список допустимых значений еще одну строчку!
Поэтому, хорошенько подумав такой стиль оформления применяйте только для абсолютно фиксированных небольших списков, например: {Да;Нет}, {M;Ж}, {Pass;Fail}

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



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

Именованный диапазон.
Оформив наш список значений в виде именованного диапазона с логичным и понятым для вас именем (в данном случае ”Проекты”). Мы можем вместо буквенно-числовой шифрограммы $A$2:$A$8 использовать осмысленное имя – Проекты.





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


4. Выводы

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


P.S. Для лентяев (к которым я причисляю и себя) в комментариях можно найти ссылу на Excel-файл, являющийся материализацией вышеизложенного материала.

С уважением,
Сергей Талалаев


Read more...

понедельник, 13 апреля 2009 г.

Нас публикуют за рубежом!



В рамках реализации проекта по перемещению мировой столицы тестирования в Минск (О.Бендер и Нью-Васюки нервно курят) состоялась публикация нашей статьи на специализированном сайте по автотестированию AdvancedQTP.com

А если серьезно, то ...


Я очень благодарен этому профессиональному сайту. Начиная с первой страницы (один слоган чего стоит: 'coz we're programmers - not users) становится понятно, что аудитория здесь собралась крайне серьезная. Мне очень повезло, что начиная свой путь с QTP я столкнулся именно с этим ресурсом. Многие сложные оказались предельно простыми после ознакомления с материалами, размещенными на сайте.
Кроме того, в силу ограничений коммерческого характера (и мне это абсолютно понятно), некоторые статьи не раскрывают все технические тонкости реализации какой-либо интересной функциональности, но дают представление об идее, которую приходится доводить до ума самостоятельно (что потрясающе интересно).

Думаю, что заслуженных диферамбов получилось достаточно :)

В силу всего вышесказанного, моей естественной реакцией было поблагодарить наших коллег и по возможности внести лепту в продвижение ресурса (не говоря уже про собственное тщеславие :). Тем более, что были самоcтоятельные мысли и наработки, которыми давно хотелось поделиться.

Честно говоря, были некоторые сомнения насколько окажется интересным материал, попадает ли он в тематику сайта, уровень владения языком опять-же. Но, спасибо активисту и основному редактору ресурса - Yaron Assa за его позитивный настрой и активность, статья была принята с хорошей оценкой с его стороны.

Поэтому, приглашаю вас во-первых, посетить этот действительно профессиональный ресурс, а во-вторых, порадоваться вместе с нами: AdvancedQTP-Universal class for data manipulations

С уважением,
Сергей Талалаев

С большой признательностью к моей коллеге Анне Валерьевне.

Read more...

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

Учим тестированию студентов!

В одном из своих постов я уже говорила о том, что среди прочих грандиозных планов - преподавание курса по тестированию ПО студентам БГУИР.

Свершилось!

И вот уже с 11-го марта дважды в неделю я наслаждаюсь общением со студентами на тему тестирования!
Признаться, до начала курса настороженно относилась к тому, как пойдет общение. Но, как ни странно, студенты ведут себя очень заинтересованно и активно. И что особенно приятно - они задают вопросы! А это значит, что:
- Они не боятся
- Они слушают
- Они пытаются разобраться
- Им небезразлично
- И, надеюсь, они, в итоге, усваивают
По поводу последнего утверждения могу сказать следующее: кое-что усваивают точно, потому что часто слышу: "а вот Вы говорили так-то", "а это называется так-то", "а такие-то тесты писать будем?" и т.д. и т.п.
Ну, а все остальное мы проверим на итоговой работе...

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

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

Пока, как говорится, "Учиться! Учиться! и еще раз - Учиться!"
Ждем результатов :)

Всегда ваша,
Наташа Густыр


Read more...

четверг, 2 апреля 2009 г.

QTP: Сравнивая с …
Универсальный класс для работы с данными


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

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


1. Введение

У меня уже был опыт работы с продуктами HP Mercury, но он относился к предыдущей линейке, я имею в виду WinRunner. Естественно я ожидал некоторого сходства в процессах скриптостроения и организации самого фреймворка. Поэтому по свежим следам постараюсь изложить замеченные мною интересные моменты и привести свои примеры реализации некоторых функций.


2. Работа с Excel-данными

Еще работая с WinRunner, я убедился, что встроенная реализация Excel хранилища не настолько гибка, как мне бы хотелось. Поэтому, как всегда, я приготовился к миграции своих процедур для работы с Excel. И был немного удивлен отсутствию встроенных средств работы с БД. Но эта задача вполне по силам, когда за плечами вся мощь VB :)


2.1. Основные задачи

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

Эти трудносовместимые вещи отлично реализуются посредством встроенной в Excel валидации входных данных и также прекрасно уничтожаются попыткой редактирования Excel таблицы напрямую из QTP.
Более того уничтожается также любое кастомное форматирование, без которого нормально читаемая таблица превращается в клетчатый текст.

Было до вмешательства из QTP:



Стало после редактирования из QTP:



Чтобы избежать подобных казусов я давно применяю прямую вычитку из Excel файлов в массивы, используя для этого стандартные ODBC источники. Данная техника успешно прижилась уже на следующих тестовых фреймворках: Rational Robot, IBM Rational Functional Tester, WinRunner и надеюсь QTP

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


2.2. Предварительные шаги

В Excel документах имеется функциональность которая позволяет выделять значимые для пользователя подмножества ячееек в специальные структуры. Такие структуры называемые “именованными диапазонами” обеспечивают возможность обращаться к ним к ним через логические имена.
Кроме того (что гораздо более значимо для нас) такие диапазоны становятся видны как стандартные ODBC таблицы из внешних приложений.

Итак, для оформления требуемой совокупности ячеек в качестве “именованного диапазона” необходимо выполнить следющую последовательность действий:
- выделить все ячейки, планируемые для оформления в именованный диапазон
- создать именованный диапазон через “Define name” диалог (Formulas > Define Name)



или напрямую введя имя диапазона в Navigation Bar.



Для проверки корректности вновь созданного именованного диапазона – выделите все ячейки диапазона и проверьте значение в Navigation Bar. Он должен содержать логическое имя вместо A1 нотации.

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


2.3. Со стороны функциональной библиотеки

После всех подготовительных шагов осталось совсем немного поработать руками, а точнее пописать код.
Раз уж QTP 9.5 предоставил нам замечательную возможность работать c “почти” объектами – грех было бы ей не воспользоваться. Поэтому весь наш функционал мы гордо завернем в класс с благозвучным названием TestData.

Стоит напомнить, что QTP не видит напрямую классы, объявленные во внешних библиотеках, поэтому для каждого класса должна присутствовать функция создания экземпляра класса, в данном случае – CreateTestData

Кроме того мы должны иметь возможность инициировать наш класс не только через загрузку из Excel источника но и напрямую из кода. Именно для этих целей появились два метода: SetData и GetData


Public Function CreateTestData ()
Set CreateTestData = new TestData
End Function

Class TestData
Private mTestTable()

Private Sub Class_Initialize()
End Sub

Private Sub Class_Terminate()
Erase mTestTable
End Sub


' @Documentation Initiates TestData object with external data
'-----------------------------------------------------------

Public Sub SetData (DataArr())
Dim i,j

ReDim mTestTable(UBound(DataArr, 1), UBound(DataArr, 2))
For i=0 to UBound(DataArr, 1)
For j=0 to UBound(DataArr, 2)
mTestTable(i,j) = DataArr(i,j)
Next
Next
End Sub


' @Documentation Extracts data from TestData object
'---------------------------------------------------

Public Sub GetData(DataArr())
Dim i,j

ReDim DataArr(UBound(mTestTable, 1), UBound(mTestTable, 2))
For i=0 to UBound(mTestTable, 1)
For j=0 to UBound(mTestTable, 2)
DataArr(i,j) = mTestTable(i,j)
Next
Next
End Sub


Итак, мы вплотную подобрались к центральной части нашего функционала – вычитке данных из Excel источника.
За данную часть функционала отвечают два взаимосвязанных метода: GetArrayFromStore и LoadFromStore
Первый позволяет нам выгрузить вычитанные данные во внешний массив, минуя наш класс, а второй наоборот – инициирует наш класс вычитанными данными.


' @Documentation Extracts test data from the Excel store
'------------------------------------------------------

Public Sub GetArrayFromStore(Arr(), TableName, StoreName)
Dim Connection
Dim i, j, fieldcount, rowsfetched
Dim ArrTemp()

Set Connection = CreateObject("ADODB.Connection")
Connection.ConnectionString = "DBQ=" + StoreName + _
";Driver={Microsoft Excel Driver (*.xls)}" + _
";DriverId=790;FIL=excel 8.0;MaxBufferSize=2048" + _
";MaxScanRows=8;PageTimeout=5;ReadOnly=1" + _
";SafeTransactions=0;Threads=3;UserCommitSync=Yes"
Connection.Open

Set ConnRs = CreateObject("ADODB.Recordset")
ConnRs.CursorType = 3
Call ConnRs.Open("select * from " + TableName, Connection)

fieldcount = ConnRs.Fields.Count
Redim ArrTemp(fieldcount - 1, 0)

'column names adding
for j=0 to fieldcount - 1
ArrTemp(j,0) = ConnRs.Fields(j).Name
next

rowsfetched = 0
ConnRs.MoveFirst()
While not ConnRs.Eof
rowsfetched = rowsfetched + 1
Redim Preserve ArrTemp(fieldcount - 1, rowsfetched)
for j=0 to fieldcount - 1
ArrTemp(j, rowsfetched + i) = ConnRs(j).value
next
ConnRs.MoveNext()
Wend
Connection.Close

'matrix transposition
Redim Arr(UBound(ArrTemp,2), UBound(ArrTemp,1))
for i=LBound(ArrTemp,1) to UBound(ArrTemp,1)
for j=LBound(ArrTemp,2) to UBound(ArrTemp,2)
Arr(j,i) = ArrTemp(i,j)
next
next

End Sub


' @Documentation Loads test data from Excel store to the TestData object
'-----------------------------------------------------------------------

Public Sub LoadFromStore (TableName, StoreName)
call GetArrayFromStore(mTestTable, TableName, StoreName)
End Sub


Как вы можете заметить, ничего сверхъестественного в реализации данного функционала нет. Более того очевидно, что с небольшими модификациями такую же процедуру можно применять для вычитки данных из любого ODBC источника.
Нам осталось добавить несколько сервисных методов, чтобы наш класс стал действительно удобным в использовании: GetCellByIndex, GetCellByName, ColumnCount, RowCount


' @Documentation Gets cell value by row-column indexes
'------------------------------------------------------

Public Function GetCellByIndex (RowIndex, ColumnIndex)
GetCellByIndex = mTestTable(RowIndex+1, ColumnIndex)
End Function


' @Documentation Gets cell value by column name and row index
'-------------------------------------------------------------

Public Function GetCellByName (ColumnName, RowIndex)
Dim j

for j = 0 to UBound(mTestTable,2)
If (ColumnName = mTestTable(0,j)) Then
Exit For
End if
next

GetCellByName = mTestTable(RowIndex+1, j)
End Function


' @Documentation Returns number of columns into the test data table
'------------------------------------------------------------------

Public Function ColumnCount()
ColumnCount = UBound(mTestTable, 2)
End Function


' @Documentation Returns number of rows into the test data table
'---------------------------------------------------------------

Public Function RowCount()
RowCount = UBound(mTestTable, 1) - 1
End Function


2.4. Со стороны тестового скрипта

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


Dim TestArr() ‘Dynamic array
Dim TestD

Set TestD = CreateTestData()

Сall TestD.LoadFromStore("NamedRange", "C:\ExcelStore.xls")
Сall TestD.GetArrayFromStore(TestArr, "NamedRange", "C:\ExcelStore.xls")
‘Call TestD.GetArrayFromURL(TestArr, "OrgChart@"+ "C:\ExcelStore.xls")

Call TestD.SetData(TestArr)
Erase TestArr
Call TestD.GetData(TestArr)

Print TestArr(1,1)
Print TestD.GetCellByIndex(2,2)
Print TestD.GetCellByName("Name", 2)
Print TestD.RowCount
Print TestD.ColumnCount


Обращаю ваше внимание, что массив (если вы решите выгружать данные из TestData объекта) должен быть динамическим, а не статическим.

Для более глубокого понимания функционала предлагаю пройтись по нему в режиме отладки и внимательно проконтролировать весь процесс.

Вы также наверняка заметили одну закомментированную функцию, я имею в виду GetArrayFromURL.
Я использую данную функцию для удобной реализации вложенных данных. В этом случае на уровне Excel каждая строка должна содержать дополнительную колонку, в которой хранится URL связанного массива данных.



Предлагаю вам реализовать данную функциональность самостоятельно.


3. Выводы

Возможно, кого-то, во время прочтения статьи, не покидало ощущение бесполезности реализации дополнительной функциональности имея стандартные средства работы с Eхcel. Частично я уже объяснял причины необходимости этого выше (Основные задачи). Но кроме этого хотелось бы еще добавить в копилку знаний несколько замечаний.

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

С уважением,
Сергей Талалаев

С большой признательностью к моей коллеге Анне Валерьевне.

Read more...

понедельник, 2 февраля 2009 г.

Сертификация: За и Против

Пора!

Пора и мне, наконец, сказать, что я думаю по поводу сертификации тестировщиков и как я себе ее вижу.

Начну с хорошего.

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

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

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

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

5. Международная сертификация позволяет специалисты во всем мире говорить на одном профессиональном языке, а также по одной шкале оценивать знания.

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

А теперь немного горькой пилюли.

1. Сертификации бывают разные… К сожалению, не всякой сертификации можно доверять (а можно ли вообще хоть какой-то?). Глупые вопросы, ни коим образом не проверяющие даже знание теории, не могут быть показателем уровня специалиста.

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

3. Точно так же, как сертификат иногда помогает найти лучшую работу, он может и затруднить ее поиски. Я, например, знакома с системным архитектором, имеющим целый ряд сетрификатов и по девелопменту, и по менеджменту, но не способному настроить Windows-сервис по инструкции.
Есть мнение, что, не имея достаточно аргументов, чтобы доказать свой профессионализм, люди стараются получить как можно больше сертификатов. Поэтому к обилию сетрификатов я отношусь более, чем скептически :)

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

Всегда ваша,
Наташа Густыр


Read more...