Тестирование инсталляторов в Windows, когда надо быстро и дешево

в 9:51, , рубрики: autoit, тестирование, метки:

Счастливы веб-тестеры, бери селениум и не ошибешься. Счастливы java-tester'ы — для них есть тест-фреймворки, в особо тяжелых случаях- siculi. Принесли на тесты консольные приложения — тут приятны python, perl. А как же desktop? Тестирование приложений blackbox в windows, в частности — инсталляторов (например пакетов msi) привело меня в стан autoit, ввиду того, что автоматизация у меня каждый раз напарывается на одни и те же грабли, которые я выделил в следующее

Что надо от автотеста инсталлятора:

  1. Кликать, вместо меня, там где надо — в русской и английской версиях интерфейса и чтобы без правки исходников. Для этого есть много разных способов, но мне больше понравился путь Аutoit — достаточно знать имя экземпляра объекта и можно послать ему сообщение о нажатии, единственный минус — надо знать имя окна, где расположена наша кнопка, как на русском, так и английском.
  2. Не парить кучей одинакового кода, например, если для нажатия кнопки 2 или кнопки 3 мне надо пройти путь через окна 1, 2 и 3, я бы хотел объединить нажатие кнопок в окнах 1, 2, 3 в некую абстракцию «путь к кнопкам 2 и 3» и вызывать ее по мере надобности.
  3. Отчеты о завале, докуда успел докликать, вобщем, что делал. Может быть даже делать скрины перед нажатием кнопочек?
    Скрытый текст
    Как-нибудь потом реализую
  4. Отчет о результате если все сделал, смоук тест о том, что все действия реально выполнились, а не что кнопки нажались. Для инсталлятора — появились ли файлы, активны ли службы, запускается ли интерфейс.
  5. Не хочу перекомпилировать и раскидывать новые еxe. Хочу править завалившийся автотест прямо на машине где он завалился, среда написания автотеста не должна вносить изменений в окружение — JAVA, .net, etc. Сотни случаев — у меня тесты прошли на ура, у клиента нет — приложить какой-нибудь .net забыли. В основном по этой причине отвалились варианты использования siculi- очень уж накладно откатывать java, для проверки, что без нее все тоже не работало.
  6. Тестер в обычном мире, полном боли и отчаяния, не том что показан в маркетинговом гладком ролике о tfs это если сильно повезет — ты и девочка, которая аккуратно идет по тест-плану (мне вот не везет и девочка отсутствует). Ей не нужен python, тысячи тысяч возможностей из cpan. Нужно — убрать рутину. Еще бонусом в тленной реальности тестерами будут на пол-ставочные студенты, круто, но как только студент освоит perl, python, он сбежит в кодеры и сильно повезет, если он успеет выполнить ту задачу по тестированию, которую ему ставили. Так я пришел к мысли о минимуме возможностей для программирования во время тестирования.
  7. Путь выполнения не на всех операционных системах одинаков, где-то появляется окошко uac, где-то нет, я не хочу заморачиваться на это каждый раз. Должен быть способ какого-то ветвления при выполнении тестового пути.

Сведя все в список я пришел к следующей идее — мне нужен свой кликер окошек с настройками в ini-файлах и отчетами.
Ок, учтем опыт поколений, будем использовать unix-way: разобъем задачу на две части — кликер и формирователь отчета.
Кликер кликает по указанным в простейшем, желательно самодокументированном, текстовом файле объектам — кнопкам, имитирует нажатия с клавиатуры.

Формирователь отчета — отдельная прожка, пишется под каждый конкретный случай, может проверять службы, создание в нужном месте файликов, сравнивать вывод к примеру команды dir c эталоном и проч если, надо. В большинстве случаев его даже не надо, тк опыт показывает, что постоянно требуется проверять новый функционал и его придется смотреть самостоятельно.

Пример настроек для кликера: файл ways.ini, в котором содержатся уникальные пути выполнения теста:

Скрытый текст

[PathToButtonSetup]
LogMessage=Take First Window, push button1
WindowsNameEnglish=System Setup
WindowsTextEnglish=Welcome to
Element=[CLASS:Button; INSTANCE:1]
WindowsNameRussian=Установка Системы
WindowsTextRussian=чтобы выйти из мастера
SendKeyText=
LogMessage=Take second Window, push button2
WindowsNameEnglish=System Setup
WindowsTextEnglish=Welcome to
Element=[CLASS:Button; INSTANCE:2]
WindowsNameRussian=Установка Системы
WindowsTextRussian=Вы устанавливаете
SendKeyText=
[Clicksetup]
LogMessage=Take Therth Window, push button1
WindowsNameEnglish=System Setup
WindowsTextEnglish=Complete
Element=[CLASS:Button; INSTANCE:1]
WindowsNameRussian=Установка Системы
WindowsTextRussian=Все готово
SendKeyText=
[ClickCancel]
LogMessage=Take Therth Window, push button2
WindowsNameEnglish=System Setup
WindowsTextEnglish=Complete
Element=[CLASS:Button; INSTANCE:2]
WindowsNameRussian=Установка Системы
WindowsTextRussian=Все готово
SendKeyText=

Собственно теперь, имея описание того, что можно делать с инсталлятором, соберем тестовый путь, описав его в другом ini-файле, testway1.ini.

Скрытый текст
[initials]
countOps=7
ClickerIniPath=«ways.ini»
sLogPath=«logs.txt»

[testWay]
case1=PathToButtonSetup
case2=Clicksetup

Если нам понадобится проверить кнопку кансел — сделаем другой ini файлик, testway2.ini

Скрытый текст

[initials]
countOps=7
ClickerIniPath=«ways.ini»
sLogPath=«logs2.txt»

[testWay]
case1=PathToButtonSetup
case2=ClickCancel

countOps — количество за раз считываемых настроек из ways.ini — сейчас их 7 штук: LogMessage, WindowsNameEnglish, WindowsTextEnglish, Element, WindowsNameRussian, WindowsTextRussian, SendKeyText. sLogPath — имя файла для сообщений, LogMessage. Остальное наверняка понятно из названий. Свойство Element придется определять через программку Au3Info.exe

Пример кода, что сможет работать с такими ini-файлами, clickAndType.au3:

Скрытый текст

#include <file.au3>
$sLogMsg=""
$TestWayIniPath=«clickandtype.ini»
if $CmdLine[0]<>0 Then $TestWayIniPath=$CmdLine[1]
$countOps=IniRead($TestWayIniPath,'initials',«countOps»,«7»)
$ClickerIniPath=IniRead($TestWayIniPath,'initials','ClickerIniPath',«clicker.ini»)
$sLogPath=IniRead($TestWayIniPath,'initials','sLogPath',«logs.txt»)

$TestWay = IniReadSection($TestWayIniPath, 'testWay')
If @error Then
MsgBox(4096, "", «Error occured, probably no INI file.»)
Exit
EndIf

; Прочтем выбранный путь выполнения
For $TestWayElement=1 to $testWay[0][0]
$ControlsActivities = IniReadSection($ClickerIniPath,$TestWay[$TestWayElement][1])
If @error Then
MsgBox(4096, "", «Error occured, probably no INI file. „& $ClickerIniPath&' '&$TestWay[$TestWayElement][1])
EndIf

$stopCycle=abs($ControlsActivities[0][0]/$countOps)
For $Elements=0 to $StopCycle-1
$win=$ControlsActivities[$Elements*$countOps+2][1]
$wintex=$ControlsActivities[$Elements*$countOps+3][1]
$ControlToPress=$ControlsActivities[$Elements*$countOps+4][1]
$winEng=$ControlsActivities[$Elements*$countOps+5][1]
$wintexEng=$ControlsActivities[$Elements*$countOps+6][1]
$SendString=$ControlsActivities[$Elements*$countOps+7][1]
$sLogMsg=$ControlsActivities[$Elements*$countOps+1][1]
_FileWriteLog( $sLogPath, 'Окно:'&$win&' '&$wintex&' Действие:'&$sLogMsg)

While 1
if WinActive($win,$wintex) Then
$winEng=$win
$wintexEng=$wintex
ExitLoop
ElseIf WinActive($winEng,$wintexEng) then
$win=$winEng
$wintex=$wintexEng
ExitLoop
EndIf

sleep(3)
WinActivate($win,$wintex)
WinActivate($winEng,$wintexEng)
WEnd
if $controlToPress<>“» then
ControlClick($win,$wintex,$ControlToPress)
EndIf

if $SendString<>"" Then
Send($SendString)
EndIf
_FileWriteLog( $sLogPath, 'Done')
Next
Next

Прожка для запуска требует параметр — имя файла для получения настроек (testway2.ini, например, в котором указано, что выполнить из файла ways.ini).

Как же всем этим хозяйством добиться ветвления из пункта 7? Все очень просто, при запуске тест виснет в трей и ждет появления указанного окошка, можно параллельно запустить несколько программок-автотестов, одна из которых, к примеру, будет реагировать на окошко с требованием ввода пароля, введет его и изначальный тест продолжит свое выполнение как будто ничего не случилось.
Про вторую прожку — формирователь отчета я пожалуй не буду писать, очень уж там все индивидуально.

Ок, оно за меня может кликать, что дальше, Брейн? Надо избавиться от порочной практики по запуску автотеста своими руками, хорошая идея — подготовить специальные виртуалки, сделать снепшот BeforeInstallXXX, который будет содержать в автозапуске батник вида, runme.bat:

Скрытый текст

msiexec /i "\fileshareinstallinstaller.msi" /qb
start «testway1» /wait clickAndType.exe \fileshareinstalltestway1.ini

Осталось лишь размещать в файловой шаре тестируемый инсталлятор и перезагружать виртуальные машинки. Если быть достаточно везучим, можно на файловой шаре также разместить и сам автотест, тогда все изменения будут централизованы и вы сэкономите время на копировании файлов настроек testway.ini, ways.ini в каждую виртуалку.

По мере роста ваших запросов, скорее всего вы придете к мысли, что функционал runme.bat надо усложнять, насколько я могу судить, скоро предстоит реализовывать третью программку — раннер, который заменит runme.bat, и, видимо, будет уметь в зависимости от каких-то условий выбирать параметр запуска clickAndType.exe

9 из 10 ставлю на то, что все вышеописанное — это велосипед, который был изобретен уже 1000 раз 1000 разных людей и на самом деле все уперлось в то, что все они имели фатальный недостаток-написаны не мной, бонусом написаны программистами, которые в порывах максимальной универсальности нередко порождали монстров, я же, являясь основным заказчиком и пользователем был заинтересован в простоте инструмента таким его и реализовывал. Заодно скажу, что найти какую-либо информацию по тестированию инсталляторов в windows простым гуглением мне не посчастливилось. Теперь же она будет здесь.

Автор: irony_iron

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js