Отладка приложений

         

Применение утилиты Tester


Использовать Tester довольно просто. Следует создать пару Tester-объектов, стартовать или отыскать главное окно приложения, выполнить для него несколько нажатий клавиш, проверить результаты и закончить работу. Листинг 13-1 содержит пример VBScript-теста, который запускает стандартную программу Блокнот (NOTEPAD.EXE), вводит несколько строк текста и закрывает ее.

 Листинг 13-1. Использование общих Tester-объектов 

' Минимальный пример работы с VBScript Tester. В нем просто запускается

' Блокнот, вводится несколько строк текста и Блокнот закрывается.

' Создать объекты системы и ввода.

Dim tSystem

Dim tInput

Dim twin

Set tSystem = «Script.CreateObject ( "Tester.TSystem")

Set tInput = WScript.CreateObject ( "Tester.TInput")

'Запустить Блокнот.

tSystem.Execute "NOTEPAD.EXE"

' Ждать 200 миллисекунд.

tSystem.Pause 200

' Попытка найти главное окно программы Блокнот.

Set twin = tSystem.FindTopWindowByTitle ( "Untitled - Notepad")

If ( twin Is Nothing) Then

MsgBox "Unable to find Notepad!" 

WScript.Quit

 End If

' Убедиться, что Блокнот выполняется в фоновом режиме.

twin.SetForegroundTWindow

' Напечатать (ввести) первую строку.

tlnput.PlayKeys "Be all you can be!~ ~ ~"

' Повторите ввод.

tlnput.PlayKeys "Put on your boots and parachutes....~ ~ ~"

' Ввести третью строку.

tlnput.PlayKeys "Silver wings upon their chests.....~ ~ ~"

' Подождать 1 секунду.

tSystem.Pause 1000

' Закончить Блокнот.

tlnput.PlayKeys "%FX"

tSystem.Pause 50

tlnput.PlayKeys "{TAB}~"

' Сценарий выполнен!

В листинге 13-1 показано три объекта, которые Tester использует наиболее часто. Объект TSystem позволяет находить родительские окна, запускает приложения и приостанавливает тестирование. Объект TWindow, который возвращается функцией FindTopWindowByritie в листинге 13-1, является главной "рабочей лошадкой". Это — оболочка вокруг объекта HWND (дескриптора окна), содержащего полный набор свойств окна.
Дополнительно, TWindow позволяет перечислить все дочерние окна, которые принадлежат конкретному родителю. Последний объект в этом листинге — Tlnput, который поддерживает единственный метод PlayKeys, направляющий клавишные команды окну, имеющему фокус.

В листинге 13-2 показан объект TNotify, используемый в VBScript-тесте. При разработке сценариев автоматизации один из наиболее трудных случаев для обработки — когда неожиданно раскрывается окно, например, панель сообщений от утверждений. Объект TNotify делает его моментальный снимок, обеспечивая тем самым, аварийный обработчик для таких событий. Простой сценарий, приведенный в листинге 13-2, отыскивает окна с заголовком "Блокнот".

 Листинг 13-2. Использование TNotify в VBScript 

' VBScript-тест для отображения обработчиков оконных уведомлений

' Константы для подпрограммы TNotify.AddNotification . Если бы я

' использовал Visual Basic 6, то определил бы здесь константы типа enum .

Const antDestroyWindow = 1

Const antCreateWindow = 2

Const antCreateAndDestroy = 3

Const ansExactMatch = 0

Const ansBeginMatch = 1

Const ansAnyLocMatch = 2

' Создать объекты tSystem и tInput.

Dim tSystem

Dim tInput

Set tSystem = WScript.CreateObject ( "Tester.TSystem")

Set tlnput = WScript.CreateObject ( "Tester.Tlnput")

' Переменная объекта TNotify

Dim Notifier

' Создать объект TNotify.

Set Notifier =

WScript.CreateObject ( "Tester.TNotify" ,' _

"NotepadNotification_" )

' Добавить нужные уведомления. В этой демонстрации используются два

' уведомления — window destroy (ликвидация окна) и

'window create (создание окна). Все возможные комбинации уведомлений 

'см. исходный код TNotify .

Notifier.AddNotification antCreateAndDestroy, _

ansAnyLocMatch , 

_ "Notepad"

' Запуск программы Блокнот.

 tSystem.Execute "NOTEPAD.EXE" 

' Ожидать полсекунды.

 tSystem.Pause 500

' Из-за того что Visual Basic не является потокобезопасным языком,



 ' Because Visual Basic isn't thread-safe

' устанавливаем схему уведомлений, использующую таймер. Однако сообщение

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

 ' в единственном потоке. Эта функция позволяет вручную проверять 

' состояния window create и window destroy.

 Notifier.CheckNotification

' Панель сообщений в процедуре событий NotepadNotification_CreateWindow

 ' блокирована, поэтому код закрытия Блокнота не будет выполняться до тех 

'пор, пока панель сообщений не будет очищена,

 tInput.PlayKeys "%FX"

 tSystem.Pause 50

 tlnput.PlayKeys "{TAB}-" 

' Снова проверить уведомление. 

Notifier.CheckNotification

' Дать TNotify шанс перехватить сообщение о ликвидации окна.

 tSystem.Pause 100

' Отсоединить уведомления. Если вы не сделаете этого в WSH, деструктор

 ' класса никогда не получит вызова, так что уведомление останется

 ' активным в таблице уведомлений. 

WScript.DisconnectObject Notifier 

Set Notifier = Nothing

Sub NotepadNotificationCreateWindow ( twin)

MsgBox ( "Notepad was created!")

 End Sub 

Sub NotepadNotificationDestroyWindow ()

MsgBox ( "Notepad has gone away....")

 End Sub

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

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


TNotify следует использовать только для неожидаемых окон. В зависимости от того, как установлены обработчики уведомлений и как они отыскивают указанный текст в заголовке окна, можно получать уведомления и для таких окон, которые вас, возможно, не интересуют. Наиболее вероятно получение нежелательных уведомлений, когда используется родовая строка, такая как "Блокнот", и указано, что строка может появляться в любом месте заголовка окна. Чтобы избежать нежелательных уведомлений, следует при вызове метода TNotify AddNotification как можно точнее специфицировать уведомления. Процедуры обработки событий CreateWindow также должны просматривать передаваемые им TWindow-объекты, чтобы можно было проверить, что это нужное вам окно. Для процедур обработки событий DestroyWindow, которые обрабатывают родовые уведомления, следует просматривать открытые окна, чтобы гарантировать, что окно, которое вам больше не нужно, не существует.

 Речь, по-видимому, идет об имени основного, родительского окна приложения, способного порождать дочерние окна. — Пер.

Наряду с исходным кодом на сопровождающем компакт-диске вы найдете два других примера использования утилиты Tester. Первый пример, NPAD_TEST.VBS — это более полный VBScript-тест, который включает несколько повторно используемых подпрограмм. Второй — ТТ (или Tester Tester'a) — является главным блочным тестом программы Tester, и вы можете получить доступ к нему с помощью группового файла проекта. TESTER.VBG.TT — это VB-приложение, из которого можно почерпнуть основную идею применения Tester'a в программировании на Visual Basic. Дополнительно, в этих двух примерах показан объект TWindows, который является коллекцией, содержащей объекты TWindow.

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


Главная причина привлекательности языка VBScript заключается в том, что не надо компилировать тесты. Если бы вы работали в настраиваемом отладочном окружении, позволяющем легко добавлять двоичные файлы к главному приложению, то рассмотреть и применение языка Visual Basic, благодаря чему можно было бы строить тесты аналогично тому, как вы строите свое приложение. Конечно, утилита Tester не ограничивает разработчика самыми легкими языками, если вам больше нравится язык С или макроассемблер (MASM), то вы вполне можете работать с ними вместо VBScript.

Работа с объектами в Tester'e довольно проста, а серьезное внимание следует уделить планированию тестов, добиваясь их максимальной простоты и целенаправленности. Не пытайтесь возложить на них слишком много работы. Желательно, чтобы каждый сценарий тестировал отдельную операцию. Можно, например, ограничить сценарий посылкой клавиатурной последовательности в открытый файл. Старайтесь обеспечить повторное использование сценариев. Так, сценарий для открытия файла можно применять в трех различных тестах: тесте работоспособности открываемого файла, тесте неработоспособности открываемого файла и тесте поврежденное™ информации в открываемом файле. Как и в нормальной разработке, следует по возможности избегать прямого включения строковых ресурсов в текст программы, а размещать их в файлах ресурсов. Это не только упростит локализацию сценария, но поможет также при изменении системы меню и клавиш быстрого вызова.

Проектируя сценарий Tester'a, полезно задать себе вопрос: "Как проверить, что сценарий выполнен?". Лучшая идея, вероятно, состоит в том, чтобы регистрировать в сценарии состояние приложения в ключевых точках, обеспечивая автоматическое сравнение выводов последовательных прогонов. Если вы используете машину сценариев Windows (WSH-файл CSCRIPT.EXE), то можете, вызвав функцию wscript.Echo, переадресовывать вывод в файл. После того как сценарий закончит работу, можно проанализировать такой файл при помощи утилиты регистрации различий (типа WinDiff); если утилита обнаружит какие-то различия, то можно проверить правильность выполнения сценария.Имейте в виду, что следует нормализовать информацию, отбрасывая специфические детали выполнения. Например, разрабатывая приложение, которое загружает биржевые сводки, не нужно включать в вывод время последнего обновления цен.

Как быть с отладкой сценариев Tester'a? Поскольку Tester не имеет своего собственного интегрированного отладчика, a Visual Basic — имеет, то необходимо проявлять осторожность, чтобы не остановить отладчик на вызове метода Tinput.piayKeys. Если отладчик там остановится, то нажатия клавиш пойдут, очевидно, не к тому окну. Чтобы справиться с этой потенциальной проблемой, перед каждым вызовом piayKeys я устанавливаю окно, к которому посылаю нажатия клавиш, поверх всех остальных окон (вызывая метод TWindow.SetForegroundTWindow). Таким образом, можно прерваться на вызове SetForegroundTwindow, проверить состояние приложения и после этого направлять нажатия клавиш к правильному окну.



Содержание раздела