В процессе автоматизации тестирования время от времени возникают задачи, решение которых стандартными средствами инструмента тестирования невозможно. Одна из таких задач – перезагрузка компьютера во время работы тесткейса SilkTest.
 
Предположим, что нам необходимо автоматизировать процесс тестирования с самого начала, то есть с установки приложения. Также предположим, что тестируемое приложение обязательно требует перезагрузки после установки. Некоторые средства автоматизации тестирования (например, TestComplete) позволяют перегрузить компьютер, а затем продолжить выполнение скриптов с нужного нам места. К сожалению, подобной встроенной возможности нет в SilkTest.
 
Итак, постановка задачи: необходимо написать автоматизированный тесткейс средствами SilkTest, который выполняет некоторые действия, перезагружает компьютер, после чего продолжает выполнение того же тесткейса.
 
Для решения этой задачи нам понадобятся несколько вещей:
1)      Возможность проверить, до или после перезагрузки запущен тесткейс
2)      Возможность запуска тесткейса сразу после окончания загрузки операционной системы
3)      Собственно команда перезагрузки системы, независимая от SilkTest
 
Для решения первой проблемы мы воспользуемся возможностью SilkTest передавать параметры с помощью командной строки. Параметры указываются в конце командной строки и могут быть прочитаны исполняемыми скриптами с помощью функции GetArgs().
 
Для решения второй проблемы мы просто создадим в процессе работы первой части (выполняемой до перезагрузки) bat-файл, который будет помещен в папку "C:\Documents and Settings\All Users\Start Menu\Programs\Startup\". Все программы и ярлыки из этой папки запускаются каждый раз при загрузке системы.
 
И, наконец, решение третьей проблемы мы найдем, используя функцию API ShellExecute() и встроенную в Windows утилиту shutdown.
 
В качестве примера рассмотрим следующий пример. Необходимо запустить калькулятор, вычислить значение выражения «2+3», после чего перезагрузить компьютер, снова запустить калькулятор и вычислить значение выражения «72-9».
 
Прежде всего, подключим необходимый inc-файл "msw32.inc". С его помощью мы подключим объявления переменных типа DWORD, HWND и т.д., необходимые для работы с API функциями.
 
use "msw32.inc"
 
Далее объявим функцию ShellExecute(), которая позволит нам запустить утилиту shutdown для перезагрузки системы.
 
dll "shell32.dll"
       [ ] HINSTANCE ShellExecute (in HWND hwnd,in STRING lpOperation,in STRING lpFile,in STRING lpParameters,in STRING lpDirectory, in INT nShowCmd) alias "ShellExecuteA"
 
И, кроме всего этого, опишем главное окно Калькулятора, которое будет пригодно как для русской, так и для английской версии Windows.
 
window MainWin wCalc
 tag "Calculator|Калькулятор"
 
Теперь настало время собственно тесткейса. Здесь мы можем выделить одну общую часть – запуск калькулятора – так как и до, и после перезагрузки, нам необходимо выполнять операции именно в нем. Таким образом, начало тесткейса будет выглядеть одинаково.
 
if(!wCalc.Exists (0))
 wCalc.Start ("calc.exe")
else
 Print ("Calculator is already running")
wCalc.SetActive()
 
Затем мы должны либо выполнить код, который выполняется до перезагрузки, либо код, который выполняется после нее. Для этого мы воспользуемся параметрами запуска SilkTest с командной строки. До перезагрузки мы не будем передавать в SilkTest никакие параметры, то есть количество передаваемых параметров будет равно нулю. После перезагрузки мы передадим один единственный параметр «AfterRestart», который будет индикатором для того, чтобы узнать, что перезагрузка системы уже произошла. Для работы с параметрами мы используем функцию GetArgs(), которая возвращает переданные параметры.
 
if(ListCount(GetArgs()) == 0)
 // действия до перезагрузки
else if(GetArgs()[1] == "AfterRestart") // this section will run only after restarting PC
 // действия после перезагрузки с проверкой первого переданного параметра
 
Для перезагрузки системы мы вызовем объявленную функцию ShellExecute().
Кроме того, перед перезагрузкой нам необходимо создать bat-файл, который выполнится при любых обстоятельствах сразу после загрузки системы. Для этого, как уже говорилось ранее, мы создадим файл SilkTest.bat в папке "C:\Documents and Settings\All Users\Start Menu\Programs\Startup\". В этом случае мы будем уверены, что он запустится независимо от того, под каким пользователем будет загружена система.
 
HFILE hF = FileOpen("C:\Documents and Settings\All Users\Start Menu\Programs\Startup\SilkTest.bat", FM_WRITE)
FileWriteLine (hF, """{SYS_GetEnv("SEGUE_HOME")}\partner.exe"" -r ""{GetProgramDir()}\{GetProgramName ()}"" AfterRestart")
FileClose(hF)
 
В данном примере мы записываем в bat-файл вызов SilkTest с запуском определенного файла скрипта. Функция SYS_GetEnv("SEGUE_HOME") вернет нам путь, куда установлена текущая версия SilkTest (в разных версиях папка может быть разной). Функции GetProgramDir() и GetProgramName() вернут нам, соответственно, папку и имя файла текущего скрипта.
 
Теперь давайте посмотрим на полный вариант описанного скрипта.
 
[-] testcase Test_PC_Restart() appstate none
// *** Step 1:
// note: this step should be run each time (before and after restarting)
 
Print("Starting Calculator")
if(!wCalc.Exists (0))
 wCalc.Start ("calc.exe")
else
 Print ("Calculator is already running")
wCalc.SetActive()
 
// *** Step 2:
if(ListCount(GetArgs()) == 0)
 Print("Evaluating expression 2+3=")
 wCalc.PushButton("2").Click()
 wCalc.PushButton("+").Click()
 wCalc.PushButton("3").Click()
 wCalc.PushButton("=").Click()
 Print("Result: {wCalc.TextField("#1").sValue}")
 
 // Step 3:
 Print ("Modifying SilkTest.bat")
 HFILE hF = FileOpen("C:\Documents and Settings\All Users\Start Menu\Programs\Startup\SilkTest.bat", FM_WRITE)
 FileWriteLine (hF, """{SYS_GetEnv("SEGUE_HOME")}\partner.exe"" -r ""{GetProgramDir()}\{GetProgramName ()}"" AfterRestart")
 FileClose(hF)
 
 ShellExecute (0, "", "shutdown.exe", "-r -t 00", "", 1)
else if(GetArgs()[1] == "AfterRestart") // this section will run only after restarting PC
 Print ("PC has been restarted")
 Print ("Evaluating expression 72-9=")
 wCalc.PushButton("7").Click()
 wCalc.PushButton("2").Click()
 wCalc.PushButton("-").Click()
 wCalc.PushButton("9").Click()
 wCalc.PushButton("=").Click()
 Print("Result: {wCalc.TextField("#1").sValue}")
 
Запустив этот скрипт вы увидите, что сначала он выполнит действие «2+3», затем перезагрузит систему и выполнит действие «72-9».
 
Теперь несколько замечаний по поводу написанного:
1)      Если вы работаете не в английской версии Windows, а в какой-либо другой, то путь, где необходимо создавать bat-файл, будет отличаться. Например, для русской версии Windows он будет таким: C:\Documents and Settings\All Users\Главное меню\Программы\Автозагрузка
2)      Если вы используете SilkTest International или SilkTest 2006 и выше, то вам необходимо заменить строку
HINSTANCE ShellExecute (in HWND hwnd,in STRING lpOperation,in STRING lpFile,in STRING lpParameters,in STRING lpDirectory, in INT nShowCmd) alias "ShellExecuteA"
на
HINSTANCE ShellExecute (in HWND hwnd,in STRING lpOperation,in STRING lpFile,in STRING lpParameters,in STRING lpDirectory, in INT nShowCmd) alias "ShellExecuteW"
3)      Также я рекомендую при создании bat-файла добавить дополнительный параметр q непосредственно перед параметром -r. Если этого не сделать, то произойдет следующее: после перезагрузки SilkTest останется открытым, но, так как он был запущен с параметром "AfterRestart", то при следующем запуске этого же тесткейса он пройде так, как будто перезагрузка уже произошла. Параметр q указывает, что после выполнения скрипта необходимо закрыть SilkTest. В противном случае вы может потратить много времени на поиск источника несуществующей проблемы, когда всегда будет отрабатывать только та часть, которая должна отрабатывать после перезагрузки.
4)      Также я бы рекомендовал в блоке, который выполняется после перезагрузки, прежде всего выполнить удаление созданного ранее файла SilkTest.bat (см. функцию SYS_RemoveFile()). Иначе его запуск будет происходить каждый раз при старте системы. В качестве альтернативного решения можно прописать запуск тесткейса в реестр (ключ [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce]). В этом случае удалять каждый раз ключ реестра не потребуется, так как запуск тесткейса будет произведен лишь один раз после перезагрузки.
5)      Утилита shutdown доступна в Windows начиная с версии XP и выше. Для более ранних версий придется воспользоваться утилитами сторонних производителей (например, утилитой shutdown, входящей в поставку cygwin, для работы которой потребуются файлы shutdown.exe и cygwin1.dll)
6)      Естественно, для полной автоматизации данного процесса вам придется настроить компьютер таким образом, чтобы он автоматически использовал имеющуюся учетную запись при загрузке и не требовал ввода пароля.
7)      Запуск калькулятора лучше выделить в отдельный appstate
 
Скачать файл, содержащий весь рассмотренный код, можно здесь.