среда, 16 сентября 2009 г.

Скрипт отправки email на VB

Данный скрипт создавался в Visual Studio 2008. Вообщем используется Visual Basic 2008 основанный на .NET Framework. Тип создаваемого проекта Vb Console Application Project. Пример приведен для почтовых серверов mail.ru.




Module SendMail
'Задать путь к System.Net.Mail в Reference
Dim email As New MailMessage 'Если в Reference путь не задан, то можно System.Net.Mail.MailMessage
Dim smtp As SmtpClient 'аналогично как выше


Sub Main()



smtp = New SmtpClient("smtp.mail.ru", 2525) ' с 25 портом не работает
smtp.Credentials = New NetworkCredential("login", "password")
email.From = New MailAddress("aaa@evil")
email.To.Add(New MailAddress("aaa@god"))
email.Body = "test"
email.Subject = "ttt"


Try

smtp.Send(email)

Catch ex As Exception



End Try


Console.ReadKey()
End Sub




End Module


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


Думаю, что в одном из последующих постов приведу пример QTP функции для отправки email

четверг, 27 августа 2009 г.

QTP script example for automate QTP (QuickTest) operations.

Автоматизация запуска QTP тестов


В QTP есть интерфейс для обращения к его объектной модели QuickTest
Данный интерфейс реализован .dll библиотекой. В документации написано, что обертку для запуска QTP тестов можно писать на различных языках. Но наиболее удобным будет писать в среде разработки при подключенной библиотеки. Как оно и предполагается, будут доступны возможности IntelliSense. Также в QuickTest Professional Automation Object Model Reference написано, что в качестве библиотеки в reference надо указывать QTObjectModel.dll.


В данном посте я опишу свои впечатления о знакомстве с данной библиотекой



  1. Запуск QTP Application используя javascript

    Для начала можно написать простенький javascript код

    function QTP() // объявляем функцию
    {
    debugger ; // это сделано для того, что бы при запуске в браузере выскочило окно с предложением о дебаге.
    var qtApp = new ActiveXObject("QuickTest.Application"); // Создаем объект application

    while (qtApp.Launched == false ) // Проверяем запущен или не запущен QTP и если false, то запускаем
    {
    qtApp.Launch();

    };

    qtApp.Visible = true // Делаем объект видимым
    setTimeout(function() { qtApp.Quit() }, 10000); // через 10 секунд после того как QTP станет видимым он закроется


    }


    Для запуска данного скрипта осталось только сделать html файлик в котором на какой-нить элемент повесить событие onclick или onload.
    В данном случае для отладки удобно использовать Visual studio. Не пробуйте запускать данный скрипт в firefox т.к. он официально не поддерживает ActiveX.
    Вот, что можно получить в случае отладки скриптов в студии.






  2. Запуск QTP используя C#


    И так студия Visual Studio 2008. Тип создаваемого проекта C# console Application (на выходе получаем .dll и .exe файл для запуска приложения).
    Сразу скажу, что то как описано ниже отличается от тех примеров создания объекта QTP Application из справки к QTP.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using QTObjectModelLib; // здесь я использую библиотеку QTObjectModelLib.dll , вместо QTObjectModel.dll. Вроде как эту библиотеку лучше использовать , если обертка пишется на c#, но официального подтверждения этой информации я не видел.

    namespace TestRunner
    {
    class Program
    {
    static void Main(string[] args)
    {
    AppDomain.CurrentDomain.UnhandledException += (s1, e1) => { Console.WriteLine((e1.ExceptionObject as Exception).ToString()); Console.ReadLine(); }; // это нужно для того, что бы если вдруг на компе, где запускается вдруг не окажется нужной dll

    try
    {
    Testrunner(); // запуск метода в котором идет запуск QTP
    }
    catch (Exception e) // отлов возникающих ошибок и вывод их в консоль
    {
    Console.WriteLine(e.ToString());
    Console.ReadKey();
    }
    }


    public static void Testrunner()
    {
    ApplicationClass app = new ApplicationClass(); // собственно создается объект класса в котором реализованы все методы интерфейсов объекта Application

    app.Launch(); // запуск QTP
    app.Visible = true; // Делаем видимым
    Console.ReadKey(); // Ждем нажатия кнопки в Console
    app.Quit(); // После нажатия кнопки в консоли мы закрываем QTP


    // Вкратце суть строчек ниже это очистка памяти. Метод FinalReleaseComObject Освобождает все ссылки на вызываемую оболочку CLR, устанавливая счетчик ссылок соответствующей оболочки среды CLR равным 0. Далее вызываем garbage collector , т.е. сборщик мусора. Я думаю это все делать не обязательно , но т.к. по сути мы используем не управляемый код используя dll. У меня возникали различные ошибки связанные с тем, что где то, видимо не подчищалось.
    while( System.Runtime.InteropServices.Marshal.FinalReleaseComObject( app ) > 0 );

    app = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    }

    }

    }



    Кстати в случае использования QTObjectModelLib.dll , вместо QTObjectModel.dll, можно также создавать объект Application следующим образом:

    Application app = new Application();

    И это не смотря на то, что Application интерфейс.







Теперь совет, если вы при попытке запуска QTP через скрипт получаете ошибку "сервер rpc недоступен", то зайдите в Task Manager и прибейте процесс QTAutomation Agent.
И попробуйте снова.

среда, 19 августа 2009 г.

Example. QTP connection to Oracle by ADO DB provider.

Доступ к базе данных из QTP на примере Oracle


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





И просто выводить значение из БД через Output Value.

Но в силу того, что в проекте, в котором я сейчас участвую, я создаю тестовые скрипты основываясь не на записи, а на создании их в ExpertView через так называемое programmatic description (программируемое описание).
Данные возможности я не использую. Кстати в данном случае запись я не использую т.к. почему то при записи в IE начинаются глюки, не раскрываются менюшки (Написанные с использованием htc и css). При этом если отключить запись и перезайти в приложение, то все ок.



Недавно мне понадобилась брать значения для запроса из таблицы БД Oracle.
Пошуршив документацию по VB я наткнулся на Microsoft ActiveX Data Objects (ADO). Вот сразу ссылочка на API .

Итак вот пример использования данного объекта для обращения к БД Oracle из QTP и получение значения из таблицы БД.






ConnectionString="Password=pass;User ID=user;Data Source=sid2; Provider=OraOLEDB.Oracle;" ' задается строка соединения к Oracle

' Строка запроса, который будет выполнен в БД
sSql = " select word from ole_search_index where field_name='Comment' "


Set oConn = CreateObject ("ADODB.Connection") ' Создаем объект

' открываем соединение к БД с заданными в строке соединения параметрами
oConn.Open ConnectionString

' Задаем объект ADODB.Recordset, который возвращает метод
set rs=oConn.Execute (sSql)

'rs.fields(0).value fields свойство объекта Recordset возвращающает коллекцию
' объектов field, которые являются по сути столбцами таблицы


Do Until checkfield( rs.fields(0).value )' Исполнения цикла до тех пор пока не true
' также можно сделать условие привязанное к свойству EOF объекта Recordset
' свойство EOF возвращает булево значение. В кратце суть EOF это, что пройденны все
' записи полученные объектом recordset

rs.MoveNext() ' переход к следующей строчке таблицы
' по умолчанию чтение из таблицы БД начинается с первой строчки

Loop



oConn.Close ' закрытие соединения к БД

пятница, 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.