Книга рецептов SilkTest

среда, 17 декабря 2008 г.

Снова о юзер контролах.

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

Рассмотрим пример несколько примеров.

1. Пример проверки текста в текстовом поле.

[-] winclass MyTextField : HtmlTextField
[+] void IsContain(string sValue, boolean bRaiseException optional)
[+] if (this.sValue == sValue)
[ ] Log.Write("Текст {sValue} существует в поле {this.sName()}.", "VERIFY")
[+] else
[+] if (bRaiseException == true)
[ ] raise 1, "Текст {sValue} не существует в поле {this.sName()}."
[+] else
[ ] Log.Write("Текст {sValue} не существует в поле {this.sName()}.", "ERROR")


2. Пример проверки цвета текста для текстового элемента.

[+] winclass MyText : HtmlText
[+] void VerifyTextColor(string sColor, boolean bRaiseException optional)
[ ] STRING sTextColor = this.GetTextProp("$TextColor")
[+] if(sTextColor != sColor)
[+] if (IsNull(bRaiseException) == true || bRaiseException == false)
[ ] Log.Write("Неверный цвет текста в {this.sName}! Ожидаемый: {sColor}, Реальный: '{sTextColor}'.", "ERROR")
[+] else
[ ] raise 1, "Неверный цвет текста в {this.sName}! Ожидаемый: '{sColor}', Реальный: '{sTextColor}'."
[+] else
[ ] Log.Write("Верный цвет текста в {this.sName}! Цвет текста: '{sTextColor}'", "VERIFY")


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


wMainWindow.MyTextField("$username").IsContain("admin")

Данный код проверяет содержится ли текст "admin" в текстовом поле "user name".

четверг, 4 декабря 2008 г.

Проверка значений в таблицах HtmlTable.

При тестирование веб приложений приходиться проверять значения в Html таблицах. Если же таких проверок значительное колличество, то удобно написать специальную функцию для такой проверки.
Для начала в фрейме мы описываем требуемую таблицу и все ее колонки. И пишем специальную функцию для проверки значиний в определенных колонках таблицы.

Описание таблицы в фрейме.

WINDOW wWebMailBox
tag "mailbox"

HtmlTable tlbLetters
tag "$mailList"

HtmlColumn clnFrom
tag "from"
HtmlColumn clnSubject
tag "subject"
HtmlColumn clnReceived
tag "received"


Реализация функции проверки.

void VerifyValueInColumn(WINDOW wColumn, STRING sText, INTEGER nRowNumber optional)
// --------- SPECS -----------------
//
// Функция делает проверку текстового значения в html таблице.
//
// args:
// wColumn - Обьект 'Колонка' в которой необходимо проверить текстовое значение.
// sText - Текст который необходимо проверить.
// nRowNumber - Номер строки таблицы в которой нужно проверить текст (По умолчанию равен 1).
// ----------- VARIABLES ------------
STRING sValue
STRING sColumnName
// ----------- STEPS ------------
// Column
if(IsNull(wColumn) || !IsSet(wColumn))
raise 1, "Need not null value for column."
// Text
if(IsNull(sText) || !IsSet(sText))
raise 1, "Need not null value for text."
// RowNumber
if(IsNull(nRowNumber) || !IsSet(nRowNumber))
nRowNumber = 1

do
BrowserPage.SetUserOption ("ShowBorderlessTables",0.75,USEROPT_DEFAULT)
if (wColumn.HtmlText("#{nRowNumber}").Exists(5))
sValue = wColumn.HtmlText("#{nRowNumber}").GetText()
else
sValue = wColumn.HtmlLink("#{nRowNumber}").GetCaption()
sColumnName = wColumn.GetCaption()

if(MatchStr("*{sText}*", sValue))
Log.Write ("Текст '{sText}' найден в колонке '{sColumnName}' в строке номер {nRowNumber}.", "Verify")
else
Log.Write ("Текст '{sText}' не найден в колонке '{sColumnName}' в строке номер {nRowNumber}.", "ERROR")
BrowserPage.SetUserOption ("ShowBorderlessTables",0.50,USEROPT_DEFAULT)
except
BrowserPage.SetUserOption ("ShowBorderlessTables",0.50,USEROPT_DEFAULT)


Пример использования функции.

//Проверяем что в колонке "From" в первой строке надпись "Иванов Иван Иванович".
VerifyValueInColumn(wWebMailBox.tlbLetters.clnFrom, "Иванов Иван Иванович")
//Проверяем что в колонке "Subject" в пятой строке надпись "Отчет за сентябрь".
VerifyValueInColumn(wWebMailBox.tlbLetters.clnSubject, "Отчет за сентябрь", 5)

вторник, 25 ноября 2008 г.

Автологируемые контролы

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

[ ] //Пример #1
[ ] STRING sUserName = "administrator"
[ ]
[ ] wMainWnd.HtmlTextField("$user name").SetText(sUserName )
[ ] Print("В текстовое поле 'user name' был помещен текст {sUserName}.")
[ ]
[ ] wMainWnd.HtmlPushButton("$login").Click()
[ ] Print("Нажата кнопка 'login'.")

Как видно из примера, практически на каждую строчку с определенным действием приходится добавлять строку логирования этого самого действия. Хорошим решением в данном случае будет создать свой собвственный набор контролов со всеми необходимыми методами, которые будут автоматически логировать все свои действия.
Для модернизации примера приведенного выше создадим два winclass-а: MyPushButton и MyTextField с переопределенными методами Click() и SetText() соответственно.

[-] winclass MyPushButton : HtmlPushButton
[-] void Click(int iBtn optional, int iX optional, int iY optional)
[ ] Print("Нажата кнопка '{this.GetCaption()}'.")
[ ] derived::Click(iBtn, iX, iY)

[-] winclass MyTextField : HtmlTextField
[-] void SetText(STRING sValue)
[ ] Print("В текстовое поле '{this.GetCaption()}' был помещен текст {sValue}.")
[ ] derived :: SetText(sValue)

Теперь можно переписать пример.

[ ] //Пример #2
[ ] STRING sUserName = "administrator"
[ ]
[ ] wMainWnd.MyTextField("$user name").SetText(sUserName )
[ ]
[ ] wMainWnd.MyPushButton("$login").Click()

В данном случае мы вместо базовых классов HtmlTextField и HtmlPushButton используем MyTextField и MyPushButton. Мы избавились от лишнего кода и логирование будет выполненно автоматически. Результирующие файлы примера #1 и примера #2 будут одинаковы.

понедельник, 17 ноября 2008 г.

Использование API функций в SilkTest

Иногда в Silktest возникает необходимость в использовании Windows API. Например когда необходимо получить доступ к директории "Cookies" путь к которой содержит имя пользователя, под которым Вы в данный момент залогинены на компьютере. SilkTest предоставлет нам такую возможность.

Для получения доступа к функциям из внешних DLL, необходимо использовать конструкцию вида:

[-] dll dllName.dll
[ ] [ReturnType] FuncName ( [ArgList] ) [alias dllFuncName]

где:
dllName.dll - имя библиотеки dll, функции которой предполагаетс использовать.
ReturnType - возвращаемый тип. (Является необязательным параметром)
FuncName - имя импортируемой функции. Может отличаться от имени, которое указано в DLL. Если имя функции указывается другое, то необходимо указать последний параметр alias
ArgList - список принимаемых аргументов. (Является необязательным параметром)
alias dllFuncName - имя функции, как оно указано в DLL. Указывается только в том случае, если имя FuncName отличается от оригинального имени функции.

Пример:

// Импорт функции для получения имени залогиненного в данный момент пользователя.
[-] dll "advapi32.dll"
[ ] LONG DLL_GetUserName(out STRING lpBuffer, inout LONG nSize) alias "GetUserNameW"

// Использование импортированной функции.
[ ] STRING sUserName // Переменная имени полученного пользователя.
[ ] LONG nSize = 0 // Переменная длинны имени полученного пользователя.
[ ] DLL_GetUserName(sUserName, nSize)

воскресенье, 16 ноября 2008 г.

О пользе тестирования

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

Постоянные читатели