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

Synchronization in qtp

События ожидания в Quik Test Professional (QTP)


В данном посте будут расмотренны вопросы




  1. События ожидания в QTP

  2. Использование свойства Object для обращения к DOM свойствам объекта в Quick Test professional скрипте

  3. Пример programmatic Description в QTP или по русски программируемое описание в QTP

  4. Пример поиска Dom свойств объекта для использования в контексте ожидания загрузки

  5. Примеры использования методов ожидания в QTP



Как-то возник вопрос о том как оценить статус загрузки страницы браузера в QTP и ее дочерних объектов. Между прочим синхронизация очень важный момент при разработки автотестов. В будущем посте я расскажу об основных на мой взгляд правилах создания автотестов и фреймворка для набора тестов.
Первым делом пришла мысль об использование метода Sync объекта Browser.
Суть данного метода в том, что бы тест ожидал пока браузер не осуществит навигацию.
Также можно воспользоваться методом WaitProperty . Вкратце суть данного метода ожидание до того момента, когда заданное свойство объекта сравняется заданному значению свойства.
Еще можно использовать метод Exist. C данным методом все просто. Он возвращает true или false в зависимости от того существует ли заданный объект. И соответственно его удобно применять в if/else конструкциях.



Далее очень полезное свойство объектов Object, правда, к сожалению применимое только в рамках использования браузера Internet Explorer. Через данное свойство можно обращаться к различным DOM свойствам и методов указанного объекта. Приведу пример в рамках данного поста:

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



Public browdes
Set browdes = Description.Create
Browdes(“micclass”).Value=”Browser”

Function waitforload()

Set strbC=Browser(browdes).Frame(“html id:=someframe”).WebTable(“html id:=sometable”).Object. borderColor

Do Until strbC = “#00a86b”
Wait 1
Loop

End function



Но как я позже убедился в случае, если возникает ошибка БД и документ не отображается, а вместо него отображается стек трейс ошибки БД, то функция уходит в бесконечное ожидание. Т.к. в данном случае borderColor не изменяется. Также я пробовал экспериментировать со свойством Browser(browdes).Object. StatusText , но это свойство браузера менялось при каждой подгрузки картинки в документе. В итоге я решил использовать свойство фрейма в котором рисовалась таблица документа. А именно свойство readyState. И в итоге получил такую функцию.





Public browdes
Set browdes = Description.Create
Browdes(“micclass”).Value=”Browser”

Function waitforload()

Set strrS=Browser(browdes).Frame(“html id:=someframe”).Object.readyState

Do Until strrS = “complete”
Wait 1
Loop

End function




В итоге получается следующий список советов для поиска нужного свойства


  1. Прочитать про DOM свойства и методы интересуемого объекта или объектов.Например в MSDN

  2. Активно использовать Object Spy и смотреть не только Identification properties, но и Native.

  3. Определить список свойств, которые хочется использовать. И написать тестовую функцию, которая в цикле заданное количество раз обращается к данным свойствам объекта. И выводит их значения в лог например при помощи метода Print.

  4. Метод Ссылка на пример
    SyncSync in QTP
    WaitPropertyWaitProperty in QTP
    ExistExist in QTP

Пример использования метода WaitProperty в Quick Test Proffesional (QTP)


В данном примере показано использование метода WaitProperty в QTP версии 10.0
И обращение к свойствам объектов с использованием конструкции attribute/свойство





Public browdes 'Объяснять не стоит в ранних версиях постов данная конструкция есть
Set browdes = Description.Create
Browdes(“micclass”).Value=”Browser”

If Browser(browdes).Frame("html id:=someframe").WaitProperty("attribute/readyState", "complete", 4000) Then ' QTP ждет в течение 4 секунд пока свойство readyState объекта
' Frame станет равным complete. Если это произойдет до истечения 4 секунд, то
' переходит к клику по первой строке таблицы
Browser(browdes).Frame("html id:=someframe").Table("html id:=table").Object.rows(1).Click ' клик по первой строке таблицы

End If




Подробнее об передаваемых в параметр WaitProperty значениях можно посмотреть в документации к QTP

Sync method example in QTP script

Пример использования метода Sync объекта Browser и метода Exist



В данном примере показано использование метода Exist и Sync в Quick Test Professional (QTP) версии 10.0




Public browdes ' глобальное описание

Set browdes = Description.Create 'вызов метода создания описания

Function startie() ' объявляем функцию

SystemUtil.CloseProcessByName "IEXPLORE.EXE" ' закрываем все открытые окна браузера
' также при желании можно добавить SystemUtil.CloseProcessByName "FIREFOX.EXE"
' и другие браузеры
If Browser("micclass:=Browser").Exist (0) Then ' проверяем есть ли открытые браузеры
' параметр 0 в методе Exist это время в течение которого тест ищет данный объект.
' 0 значит возвращать true или false незамедлительно
Print "Есть открытые окна браузера" ' Пишем в лог
ExitAction(1) 'Выходим из теста
Else Print "Отлично!!! все окна браузера успешно закрыты" ' Пишем в лог
End if
SystemUtil.Run "iexplore.exe" ' запускаем браузер
Print "Открываем новое окно браузера" 'пишем в лог
End Function

Function openmyblog()

Browser(browdes).Navigate("http://testerway.blogspot.com")' осуществляем навигацию
Browser(browdes).Sync ' собственно метод Sync ожидающий окончания навигации

MsgBox "all done"
' Вывод сообщения. В данный кусок кода тест перейдет лишь после окончания навигации

End Function

call startie ' вызовы функций
call openmyblog




Замедлить скорость работы интернета можно при помощи различных программ, которые уменьшают пропускную способность канала или использовать "тормозную" проксю :)

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

Немного юмора. Be libirated.

Анекдот:
"На рынке по торговле рабами: Мне два белых и половинку черного!!!!"




Давным, давно ...........в далекой галактике, но я не об этом :). Когда-то работая с rational robot я обратил внимание на одну из картинок, которая появляется в процессе загрузки.





На данной картинке изображен белый мужчина сидящий за компьютером и темнокожий мужчина стоящий рядом с ним. А на фоне окно похожее на решетку.А сверху надпись "be libirated" - "будь свободен". И мне вот интересно закладывали ли авторы данной картинки скрытый смысл в духе "с rational robot ты свободен"," национальная дружба", "у нас нет расизма".

четверг, 23 июля 2009 г.

Юнит тестирование в C# на примере Visual Studio 2008. Unit test in C#.

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

  1. Что такое модульное (unit) тестирование и почему его называют тестирование белого или стеклянного ящика?

  2. Можно ли покрыть программу тестами на 100%?

  3. Как оценивают тестовое покрытие? и его достаточность
  4.  
  5. Использование mock объектов  в unit тестирование

И другие вопросы.


И так начнем. Предыстория вопроса следующая, недавно мне поступило задание написать модульный тест для тестирования изменений конфигурации поискового сервера. Писать модульные тест предстояло на незнакомом мне языке c#. Естественно обращение к поисковому серверу шло через сервис в котором вызывался определенный метод для обращения к серверу. Соответственно в итоге модульный тест создавался для сервиса. В качестве среды разработки модульного теста использовалась Visual Studio 2008. В данном примере я приведу простой пример создания модульного теста в среде VS.


И так, запускаем студию и открываем окно

Окно создания нового проекта в visual studio

В котором выбираем C# class library.

Далее пишем исходный код программы.





using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace Example
{
public class Dosomething //Объявляем класс
{


public string checksrvstatus(string url)
// метод класса возвращающий строку и принимающий на вход строку
{
if (url == "http://testerway.blogspot.com")
{
// В блоке создается запрос к странице веб сервера и далее обрабатывается ответ
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
string statusdes = myHttpWebResponse.StatusDescription;
string server = myHttpWebResponse.Server;
return ("server: " + server + " status: " + statusdes);

}
else
{

return "";

}

}
public void callchecksrv(int k)
//еще одна функция не возвращающая значение и принимающая на вход число.
{
if (k > 0)
{
checksrvstatus("http://microsoft.com");

}


Далее создаем UnitTest. Нажимаем правую кнопку мыши.


контекстное меню создания юнит теста

Появляется диалог
диалог выбора тестируемого класса, метода

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



using Example;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace TextExample
{


///



///This is a test class for DosomethingTest and is intended
///to contain all DosomethingTest Unit Tests
///

[TestClass()]
public class DosomethingTest
{


private TestContext testContextInstance;

///
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///

public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}

#region Additional test attributes
//
//You can use the following additional attributes as you write your tests:
//
//Use ClassInitialize to run code before running the first test in the class
//[ClassInitialize()]
//public static void MyClassInitialize(TestContext testContext)
//{
//}
//
//Use ClassCleanup to run code after all tests in a class have run
//[ClassCleanup()]
//public static void MyClassCleanup()
//{
//}
//
//Use TestInitialize to run code before running each test
//[TestInitialize()]
//public void MyTestInitialize()
//{
//}
//
//Use TestCleanup to run code after each test has run
//[TestCleanup()]
//public void MyTestCleanup()
//{
//}
//
#endregion


///
///A test for checksrvstatus
///

[TestMethod()]
public void checksrvstatusTest()
{
Dosomething target = new Dosomething(); // TODO: Initialize to an appropriate value
string url = string.Empty; // TODO: Initialize to an appropriate value
string expected = string.Empty; // TODO: Initialize to an appropriate value
string actual;
actual = target.checksrvstatus(url);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
}
}

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



using System.Diagnostics; // для вывода текста в debug trace

[TestMethod()]
public void checksrvstatusTest()
{
Dosomething target = new Dosomething(); // TODO: Initialize to an appropriate value
string url = "http://testerway.blogspot.com"; // TODO: Initialize to an appropriate value
Debug.WriteLine("url: " +url);
string expected = "server: GFE/2.0 status: OK"; // TODO: Initialize to an appropriate value
Debug.WriteLine("expected result: " + expected);
string actual;
actual = target.checksrvstatus(url);
Debug.WriteLine("result: " + actual);
Assert.AreEqual(expected, actual);


}

Далее прогоняем тест. И смотрим окно результата прогона теста.

отчет по результату выполнения модульного теста


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


включение определения покрытия кода модульным тестом


И теперь после прогона теста можно посмотреть следующие

покрытие кода тестом

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


выбор отображения покрытия кода тестом в самом коде

отображение покрытия кода тестом в самом коде


Очевидно, что красным выделен не покрытый тестом код. Также в Studio есть возможность управления набором тестов и другие полезные средства. Итог подводить не буду, так как думаю, что еще изучил не все возможности, которые предоставляет VS 2008 для модульного тестирования.
Использование mock объектов в модульном тестировании на C#

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

Example of QTP script function

Пример функции в Quick Test Professional(QTP). Кликанье или чтение по всем элементам таблицы



В данном примере используется так называемое "программное описание" или "Programmatic Descriptions" и еще иногда называют descriptive programming. Также в примере используется свойство всех веб объектов QTP Object. Данное свойство позволяет обращаться к DOM свойствам и методам web объектов. Но к сожалению в help к QTP написано, что данное свойство работает, только для IE (InternetExplorer).




'Данный пример будет работать только в IE. Т.к. свойство Object , которое тут используется поддерживается только для ie.

Set browdes=Description.Create 'Создается объект описание

browdes("micclass").Value="Browser" 'для описания micclass значение Browser

Function rcTable(obj, strmode, col, row) ' Функция с 4 параметрами на вход, obj - объект(таблица), strmode - строковое значение c(click) или r(read)

Dim intRowcount ' переменная для хранения числа строк в таблице

intRowcount= obj.RowCount ' подсчет числа строк в таблице

If intRowcount >0 Then ' Проверка на то, что число строк в таблице больше 0

For i=row To intRowcount ' Цикл от переданного в функцию параметра row до числа строк в таблице

If strmode="c" Then ' Ветвление для строкового параметра c(click)

obj.Object.rows(i).cells(col).Click 'клик на соответсвующий элемент таблицы. С использованием свойства Object .

elseif mode="r" Then ' Ветвление для строкового параметра r(read)

Print obj.GetCellData(i,col) ' Печать текста соответсвующего элемента таблицы в лог.

End If ' Конец ветвления для строкового параметра

Next ' Переход к следующему значению в цикле, если оно еще не достигло максимального

Else ' Ветвление , если intRowcount >0 = False

MsgBox "Пустая таблица, повторите операцию на другой таблице" ' Вывод окна с сообщением

End If ' Конец ветвления проверки числа строк intRowcount >0


End Function ' Окончание функции

Set objTable=Browser(browdes).Frame("html id:=_frmQueryList").WebTable("html id:=Hitlist1__searchQueriesList__searchQueriesDataGrid") ' Пример инициализации объекта для использования в функции

rcTable objTable,"c",3,1' Пример использования функции

четверг, 16 июля 2009 г.

Дебаг теста в QTP и pdm.dll в этом процессе. И коротко о патче QTP_00591.EXE

Это мое первое сообщение в данном блоге. Далее в своем блоге я буду публиковать различные интересные проблемы с которыми сталкивался в процессе работы и какие то свои мысли по поводу карьеры в IT в целом и тестирования ПО в частности.


В данный момент в качестве инструмента автоматизированного тестирования Web приложений я использую QTP 10.0,а в качестве браузера на котором идет веб тестирование это IE и вот однажды я столкнулся со следующей проблемой. После переноса QTP с одной машины на другую в дебаг (debug) режиме перестали отображаться текущие значения переменных. Просмотреть значение переменной можно было только через "Add watch", но при этом через него нельзя было обращаться к объектам после попытки добавления в список отображалась пустая строка как на рисунке ниже за исключением того, что была заполнена строчка Context. Итог: в QTP 10.0 в дебаг режиме перестали отображаться значения для переменных и для объектов.


пустое окно дебага в QTP

Первым делом я полез в google и на одном из буржуйских форумов увидел тему с данной проблемой. Выяснилось, что данная проблема лечится патчем QTP_00591. Вот вырезка из описания патча:
This patch fixes a problem in which objects sometimes disappeared from the Watch and Variables lists in the QuickTest Debug Viewer.
This problem was observed when Process Debug Manager 9.xx.xxxx was installed. It may also occur for later versions.

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

окно дебага после update pdm.dll

На другой машине окно дебага для аналогичного объекта выглядела вот так


Выяснилось, что на старом месте для QTP стоит вот такая библиотека pdm.dll, которая судя по всему инсталлируется вместе с QTP.

окно дебага со старой версией pdm.dll

А на новом месте для QTP была следующая библиотека pdm.dll, которая установилась вместе с Visual Studio.

новая версия pdm.dll

Отсюда вывод, что если хочется как говорится видеть больше и дальше, то надо заменить старую библиотеку на новую или произвести update данной библиотеки ,а затем установить патч. Что бы удалить старую библиотеку и поставить новую, можно воспользоваться командой regsvr32, которая удаляет и устанавливает dll библиотеки. Посмотреть справку к данной команде можно в справке Windows или вызвав cmd консоль и набрав regsvr32 без параметров. Новая библиотека установится сама в случае установки VS, но также ее можно взять из IE 8, в который она входит как я предполагаю с целью отладки javascript в браузере посредством IE Devtoolbar, который включен в ie8.
P.S. Кстати интересно, что использует firefox для отладки javascript в firebug.