вторник, 26 марта 2013 г.

Следующий пост про SQA Days, который позже

Доброго времени суток.

Хочу сразу извиниться за такую задержку с постом.

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

Что именно не понравилось в организации конференции не скажу, свое мнение и претензии я оставил организаторам, и судя по тому, что мне рассказывали? - сам я не смог приехать, - многое учли; не суть важно, в ответ на мои ли отзывы или отзывы других участников, тут личное удовлетворение от "важности" твоего голоса - вторично, главное, что я могу сказать, что конференция снова отличная, более того, что организаторы учатся на своих ошибках, а это, на самом деле, даже важнее :) И теперь, когда эти самые ошибки учтены и исправлены, я могу сказать о их наличии, не боясь того, что это может как-то навредить людям.

В общем, тогда я хотел, чтобы эмоции улеглись, - и затянул с этим, грешен, да и работы было много - зато теперь эти самые эмоции улеглись напрочь, вкупе с многими воспоминаниями :) Многое уже забыл, поэтому пост деталями будет не нагружен.

Это будет даже не столько обзор докладов, хотя планировалось развернутое повествование, даже с фото слайдов презентаций, /*кстати, кому интересно, могу просто выслать слайды тех презентаций, против распространения которых не возражали их авторы (для разных знакомых мне вредин уточняю: да, когда готовил пост два года назад, спросил разрешения на публикацию у авторов докладов:)*/, сколько мое личное спасибо авторам особенно понравившихся докладов, с пояснением, за что именно. Ни в коем случае порядок "спасибов" не говорит о предпочтении или важности/избранности (наоборот?) какого-либо доклада. Просто так сложилось :)

Первое спасибо - Алексею Чумагину за его доклад об автоматизации рутинных действий, как то: сбор логов, авторизация и ввод данных. Почему-то при слове "автоматизация" все (и я не исключение) сразу думают о тестировании регрессионном, на худой конец, - нагрузочном, и совершенно забывают про изначальную цель автоматизации - избавить тестировщика от рутинной работы, а  результат тестирования - от влияния человеческого фактора. Вот Алексей нам об этой цели и напомнил. А уж за подборку легких инструментов, включающую nnCron(http://www.nncron.ru/), iMacros (http://wiki.imacros.net/) и AutoIt (http://www.autoitscript.com), которые позволяют решать указанные задачи без привлечения тяжелой артиллерии, так просто нижайший поклон.

Второе спасибо хочется сказать Александру Барановскому за его доклад о собеседованиях тестировщиков. Тут даже не знаю, как рассказывать. На эту тему было много и докладов прослушано, и статей прочитано, но вот зацепило. Доклад был про то, как хороший и очень опытный человек структурировал этапы проведения собеседований. Четко, понятно и лаконично, без лишнего разжевывания, но и с достаточным количеством разъяснений. Кто был, получил массу полезной информации.

Третье спасибо - Игорю Бондаренко. Как-то так случилось, что я никогда всерьез не занимался тестированием защищенности веб-приложений (ну не считать же за таковое авторизацию пользователя, например :). Как что-то абсолютно неизвестное, этот вид тестирования всегда казался очень сложным, требующим особенных знаний и таланта. Вот очень хочется сказать Игорю спасибо за то, что простым языком объяснял сложные вроде бы вещи :) Да, чтобы не вводить в заблуждение: талант все-таки нужен :)

Еще спасибо Наталье Руколь за "Фишки правильных тест-менеджеров". Может быть это покажется некоторым уменьшением значимости доклада, но для меня на тот момент в нем главной была фраза о том, что - вот не ручаюсь за цитату, но смысл постараюсь передать: "рабочий  день правильного тест-менеджера начинается не с работы, а с чашки кофе". Честное слово, на тот момент это был лучший совет, который мне можно было дать. Спасибо!

Следующее спасибо (они все написаны просто "спасибо", но читать надо все-таки как "большое спасибо") хочется сказать Александру Ильину за "Полезные метрики покрытия. Практический опыт и немного теории". Я, по-моему, ему об этом говорил, если не подводит память, но повторюсь еще раз: метрики были известные, некоторые даже применялись на практике, но вот проанализировать их с помощью SMART мне даже в голову не приходило, эти два понятия просто жили в голове, абсолютно никак не пересекаясь.  За это просветление - возможность применения SMART не только как инструмента планирования (целеуказания?) - Александру большое спасибо.

Еще очень понравились доклад Екатерины Жульковой и мастер-класс (хотя он был больше похож на доклад с полемикой) Алексея Петрова о тестировщике-фрилансере. И им предпоследнее явное и особое спасибо этого поста. Было очень интересно послушать и пообщаться с людьми, которые работают в параллельной (для меня на тот момент) реальности, проанализировать и сравнить свои навыки с теми, которые востребованы во фрилансе, а также те, которые  нарабатываются таким "режимом" работы.

Кроме того, хочется сказать спасибо всем остальным докладчикам и организаторам конференции. То, что другие доклады я не упомянул, не значит, что они были плохие, просто я так устроен, запоминаю то, что именно мне кажется наиболее важным и/или интересным. А может я просто чего-то не понял :)

Последнее особое спасибо вам, за то, что дочитали досюда этот пост, опоздавший на два года, и дали мне возможность выполнить обещание :)

Одно обещание я все-таки не выполню. Кто-то из указанных выше докладчиков просил дать ему ссылку на пост, если буду писать о его докладе. Я просто не помню кто, а файл с заметками уже давно утерян при переезде на новый компьютер. Надеюсь, этот человек увидит пост сам и примет этот абзац за извинение :)

суббота, 10 декабря 2011 г.

Следующий пост про SQA Days будет чуть позже

Всем привет.
Я просто зашел извиниться за задержку с обещанным постом про доклады на SQA Days 10.
Постараюсь его сделать в кратчайшие сроки - я обещал его слишком многим, включая авторов докладов, так что не могу не написать.

понедельник, 5 декабря 2011 г.

SQA Days 10. Тестировщику 800 верст - не крюк. Пост второй: зачем люди ездят на конференции.

Мне всегда было интересно, почему люди ездят на подобные мероприятия. А когда мне интересно, я обычно начинаю спрашивать, иногда не тех, но в данном случае ошибиться было сложно - было полно представителей фокус-группы :) Так вот, на первом месте среди причин, побуждающих народ оторваться от дивана и куда-то ехать оказалось наличие повода "потусить со своими". Получается, что нам очень не хватает общения с себе подобными - хороший сигнал для всех любителей создавать разного рода региональные сообщества, есть подозрение, что в них будут вступать просто даже потому, что больше вступить некуда :) На втором месте где-то рядышком сидят желание "завести знакомства" и "повод куда то выбраться", что я сначала хотел записать в "потусить", но потом решил, что выбраться не обязательно означает потусить и наоборот, так что, - пусть живет себе самостийно. А вот самый логичный, казалось бы, повод поехать на конференцию за знаниями, чтобы чему-от новому научиться, или отучиться от плохого старого, оказался в самом конце ответов. Да, чтобы предотвратить вопросы о валидности моих результатов, сразу скажу, что точных цифр не собирал, не хватало еще с идиотским выражением лица бегать по коридору с листиком и лихорадочно всех конспектировать, так приличного человека за социолога принять могут, да не обидятся на меня оные :) Я просто задавал людям вопросы, и старался запомнить примерно суть ответов и в каком порядке в них шли указанные варианты (есть подозрение, что первым человек назовет именно наиболее близкий ему), так, чтобы в голове оставалась общая картинка, типа того, как мы видим цвет тучи: она может быть разных оттенков в разных своих точках, но человеки все равно говорят, что она "серая", "белая, или еще какая-нибудь "розоватая". Вот так и у меня осталось четкое ощущение, что ответы были по сути своей такими и проранжировались именно так. Если же кому-то хочется проверить, можно даже диссер написать, благо сейчас чего только не защищают, так что может кому и пригодится идея :)


Мне же,как и всем остальным :), хочется выделиться. Поэтому в качестве причины, побудившей меня приехать, я назову погоню за идеями. Так получилось,что на первую свою конференцию SQA Days я попал чуть-ли не случайно, меня приятель подбил, за что ему большое спасибо. И вот на этой конференции со мной стали происходить абсолютно странные вещи. Вот сидишь ты, слушаешь доклад, и вдруг начинаешь думать о чем-то совсем постороннем, не особо даже связанным с тем, о чем вещает докладчик. Просто информация для тебя если не новая, то смотрят на нее совсем не стой стороны, с какой ты сам. А дальше мозг просто отталкивается от этой информации и начинает "ее думать", причем забирается в какую-то совсем отдаленную загогулину. Так вот эта загогулина обычно стоит того, чтобы отвлечься. Самое интересное, что происходит это довольно быстро, ты даже успеваешь вернуться к докладу до того, как потеряешь его нить. Так что на выходе ты имеешь информацию по докладу, откуда можно сплагиатить отличные идеи, контакты докладчика, с которым можно потом пообщаться вне конференции, плюс несколько самосгенеренных идей, пара из которых, если их хорошо проанализировать да реализовать, приводят впоследствии к каким-то плюшкам. Для меня это очень весомый довод в пользу поездки, вот и катаюсь :)


Кстати, одной из простеньких идей такого рода могу поделиться - сильно помогает на конференциях. Оказывается, фотоаппарат, особенно мегазумник, это не только приятно жужжащая штуковина, но и отличное средство конспектирования. Я например, перед началом доклада настраиваюсь так, чтобы экран проектора занимал весь кадр, и потом просто отщелкиваю их по порядку, занося комментарии к себе в блокнот в том же порядке. У этой методики есть еще один плюс: обычно материалы конференций выкладывают сильно позже, а у вас они будут сразу же. Кстати, я пытался писать виде со звуком на фотик, но или у меня камера не та, или оператор бездарен, но звук просто теряется, да и места кушает на карточке многовато, так что я за отсъем кадров :)

На этом я собираюсь закончить второй пост про мое посещение SQA Days 10. Будет еще третий, про собственно конференцию, про то, что было хорошо, и что было плохо, а также о понравившихся докладах. Постараюсь выложить этот пост сегодня или завтра вечером. До встречи :)

воскресенье, 4 декабря 2011 г.

SQA Days 10. Тестировщику 800 верст - не крюк. Пост первый.

Привет всем, сегодня вернулся с конференции в области обеспечения качества ПО SQA Days, причем, аж 10-й. Очень хочется поделиться впечатлениями, тем более, что для меня это еще и была первая моя поездка в Москву. Вернее, не так, это был первый раз, когда я там был не просто транзитом, а еще и на какое-то время подзадержался. Впечатления мои сильно неоднозначные, ну да обо всем по порядку, сплагиачу Гагарина: "Поехали!"

Говорят, в Москву надо приезжать в начале осени или же в конце весны, когда все еще или уже зеленое, улицы чистые и вообще все воспринимается по-другому, потому как вокруг тепло (но не душно), хорошо и ледяная крошка в лицо не летит :)

Думаю, описывать дорогу в Москву смысла особого не имеет, посему начну с момента моего туда прибытия. Встретила нас, - а нас из Харькова понаехало аж шестеро - бывшая наша столица очень странной погодой, никогда не думал, что такое возможно в принципе: температура ниже нуля (смотрел на каком-то градуснике) и одновременно с этим - сырость! Вообще, мне ведь говорили, что это время года не самое лучшее для посещения Москвы, так вот - не обманули :) Наблюдаемая мною картинка состояла из промозглой сырости и серости, вездесущих луж, то и дело норовящих подернуться ледком, деревьев, - голых и каких-то странно по-человечески озябших и постоянных потоков таких же озябших от налетающего периодически холодного влажного и очень противного ветра людей, которым до тебя нет никакого дела, ибо своих дел явно невпроворот.

Но не все так плохо, это мрачное впечатление было достаточно быстро исправлено начавшимся снегопадом. Знаете, бывает такой крупный не так чтобы редкий, но и не сплошной стеной снег, который летит себе, тихо кружась, и плавно ложится тебе под ноги, и не только. Так вот, именно такая красота и имела место быть, так что свой первый снег в этом году я увидел именно в Москве, так что спасибо ей большое за это маленькое чудо, за которое я мгновенно простил все прежние выкрутасы с погодой.

Москва, которую я увидел, предстала поистине городом контрастов: калейдоскоп ухоженных кварталов и дорог с яркими оконищами магазинов вдоль них сменялись видом умученных троллейбусов под стать нашим и видами быта живущих под лестницей одного из упомянутых не то магазинов, не то еще каких объектов коммерческого городского пейзажа бомжей :) Двуглавые орлы как-то очень спокойно сидели рядом с красным звездами (это я так в Кремль прогулялся), новые вагоны метро, контрастировали с более привычными харьковчанину вагонами более старых типов, но отличавшимися здесь совершеннейшей убитостью - в них было иногда страшно ездить, настолько сильно они скрипели, сипели и стучали, кажется - готовы развалиться в любой момент, но ничего, как оказалось все более-менее в порядке, доказательством этому являюсь я сам - таки ж доехал :)

В общем и целом, впечатления остались абсолютно не целостные, лоскутное одеяло, а не пейзаж :)

Но да Бог с ним, я ж сюда приехал не Москву смотреть, хотя смотреть не кривя душой скажу - есть на что: на Покровский Собор, он же - Храм Василия Блаженного, который напрочь перебивает любые негативные впечатления самим своим существованием, на Старый Арбат, который, и это буквально чувствуется кожей, обволакивает тебя какой-то паутиной суетливой, но добродушной радости и оставляет просто великолепное впечатление. Еще, просто завораживает обилие книг в книжных магазинах, да и сами магазины тоже - меня занесло в Московский Дом Книги на Новом Арбате, честно скажу, сумка моя сильно потяжелела :)

Кстати, я убедился ,что мысли материальны. Например, Россию показывают в фильмах как страну пьяных людей в тельняшках и шапках-ушанках. Так вот, так оно и есть - на Старом Арбате я видел множество пьяных и именно в упомянутых шапках ,причем с огромными красными звездами или гербами Союза на них. Вот только это не местные жители, а туристы :) Их действительно таких много, впечатление просто феерическое :)

Опять отвлекся,  главной целью моего приезда было не поглазеть на Москву, а, как можно догадаться из заголовка поста :), меня сюда заманила проводившаяся тут 2-3 декабря конференция тестировщиков. Причем, юбилейная, десятая по счету. Один из любимых моих авторов, М.Е. Литвак, утверждает, что "мужчина - ленивое животное", и по-моему он прав :) Вот ни в жисть не поперся бы я в такую даль ,если бы у нас в Харькове, было что-то хоть отдаленно подобное в обозримом будущем. Зато появилась возможность пост написать и даже не один :) Этим я и ограничусь пока, а то спать хочется, ну хоть иногда :)

Вторую часть выложу завтра, обещаю.

пятница, 11 ноября 2011 г.

UIAutomation. Ограничение одного теста{!|?}

Сегодня хочется рассказать про еще один трюк, облегчающий жизнь.

Вообще, при знакомстве с UIAutomation возникает большое количество вопросов. Одним из них, и, как по мне, наиболее важным, является то, что нативно инструмент поддерживает только один тест.

Выглядит это так. Вы просто указываете файл с именем теста в окне инструмента. И выполняться будет ровно этот один тест. Если хотите другой тест, - останавливаете текущий, указываете новый и запускаете его на выполнение. И так до тех пор пока у вас не кончатся тесты...

Мое терпение лопнуло раньше. Посему, поделюсь как удалось решить эту проблему.

Для начала, расскажу о директиве #import, которую Apple добавила в свою реализацию JS для этого инструмента. Директива имеет сложное и непонятное название, а действие ее сводится к подключению других JS файлов с какими-нибудь нужными классами, фукнциями и даже данными. Если файл лежит в той же папке, что и исходный, просто укажите его имя в двойных кавычках. Если нет, - указываете относительный путь к нему. Например, так:

#import "Test.js";

или так

#import "Tests/SmokeTest.js";

Эта команда позволит нам в будущем строить нормальный фреймворк для нашего приложения.

Теперича хочется чуток подотвлечься и поговорить о том, что такое тест, но только не тест вообще, а автомейшен тест. По большому счету, это просто набор команд с входящими и исходящими данными. Входящие данные - это, обычно, какие-нибудь инициализационные значения, исходящие - результат теста в виде pass/fail (если кому нравится можно хоть в булевых значениях определять :) Еще у теста должно быть имя, дабы отличить эту штуковину от собратьев. Если кому это напомнило функцию, то это, как говорил Винни, неспроста - функция и есть, ну, или метод.

Так, ладненько, теперь так же быстро перепрыгнем на организацию тестовых наборов. Мне лично (не удивительно, почти 100% стандарт) очень по душе концепция тест-классов и тест-методов, согласно которой у вас есть несколько тест-классов, содержаших, в свою очередь, набор методов - тестов. Каждый класс относится или к какой-либо однородной группе функциональности, или объединяет тесты, схожие по реализации. Лучше, когда выбран первый вариант, который про однородность функционала, - жить потом проще :)

Ффух, наотступались. Кстати, за что люблю такие отступления, так это за то, что потом можно, например, не объяснять, что за классы и методы я сейчас буду писать :) Для облегчения работы с тестами напишем простенький класс, в котором будем хранить имя теста и результат его прогона:

/** @class Represents a test
* @author Sergey Lyopka
*/
function Test(/**String*/Name, /**bool*/Result) {
    var name = Name;
    var result = Result;

    /** Returns the test name.
    * @type String
    */
    this.getName = function () { return name; }

    /** Returns the test result.
    * @type bool
    */
    this.getResult = function () { return result; }
}
Я не буду особо расписывать, идея, думаю, понятна, а реализовать можно как угодно. Замечу только, что это не тест-метод, просто некоторая сущность, используемая для удобства.

Теперь, давайте посмотрим собственно на тест-класс и тест метод в нем:

// Test Class for FileManager tests
function FileManagerTests() {
    /*Covered test cases:
    * 16756
    */
    this.test16756 = function (log) {
        log.message("Covered Test Cases: 16756")
        testResult = true;

        var window = new MainWindow();
        waitForVisible(window.NavBar(), 10);

        if (!window.Table()) { log.debug("Table view was not found."); testResult = false; }
        else {
            if (1 != window.Table().cells().length) { 
              log.debug("Unexpected number of visible table cells was found: " +
                window.Table().cells().length); testResult = false
            }
            if (!window.LocalFolder()) { 
              log.debug("Local Folder was not found"); 
              testResult = false
            }
        }
        return testResult;
    } //test16756
}

В принципе, тоже все понятно: тест-класс FileManagerTests, сождержащий тест-метод test16756. Если код метода вызывает некоторые сомнения по поводу того, поддерживаются или нет такие функции как, скажем, waitForVisible, просто не обращайте внимания, - это реальный тест, который успользует кучу утилитных фукнций-оберток, которые были дописаны для облегчения работы с тестами. Даст Бог, и про них как-нибудь расскажу.

Осталось показать, как это все выполняется. Вспоминаем, что UIA может выполнять только один тест за раз. Вот в коде файла, который был предназначен для этого самого единственного теста, мы можем теперь вызывать наши классы и тесты, собственно вот так:

#import "Lib/TestSet.js";
#import "Lib/Logger.js";
#import "Tests/SmokeTest.js";

//Logger Init
var log = new Logger(true, false);
log.start("Smoke Test");

//Test Set filling
var testSet = new TestSet();
testSet.addTests(new SmokeTest(), log); //собственно, это и есть добавление

//Test Results
tests = testSet.getTestSet();

for(test in tests)
  if (tests[test].getResult()) log.pass(tests[test].getName());
  else log.fail(tests[test].getName());
 
if(testSet.getResult()) log.message("Test Set has completed successfully.");
else log.message("Test Set has completed unsuccessfully.");

Чтобы до конца понять, как строка testSet.addTests(new SmokeTest(), log); способствует выполнению тестов, осталось рассмотреть вспомогательный класс TestSet, который служит для формирования тестовых наборов.

#import "Test.js";


/** @class Represents a test set.
  * @author Sergey Lyopka
  */
function TestSet(){
  var tstSet = new Array();
  var result = true;
 
  /** Adds single test to the test set.
    * @param {String} testName The name of the adding test.
    * @param {bool} testResult The result the test execution.
    * @type null
    */
  this.addTest = function(testName, testResult){
    if(!testResult) result = testResult;
    tst = new Test(testName, testResult);
    tstSet.push(tst);
  }// addTest

  /** Adds entire test class to the test set.
    * @param {Test} testClass The name of the adding test class.
    * @param {Logger} log The current thread logger.
    * @type null
    */
  this.addTests = function(testClass, log){
    var testNames = getTests(testClass);
    for(var i in testNames){
      log.message(testNames[i] + " started.");
      try{
        this.addTest(testNames[i], testClass[testNames[i]](log));
      }
      catch(err){
        log.issue(testNames[i] + " test has terminated abnormally!");
        this.addTest(testNames[i], false);
      }//catch
      log.message(testNames[i] + " finished.");
    }
  }// addTests
 
  /** Returns the result of test set execution.
    * If all the tests passed, then result is true.
    * If at least one test failed, then result is false.
    * @type bool
    */
  this.getResult = function(){return result;}
 
  /** Returns array with all the tests.
    * @type Array
    */
  this.getTestSet = function(){return tstSet;}
   
  /** Gets all the tests (methods with 'test' at the name) from the test class. Internal.
    * @param {Test} testClass
    * @type Array
    * @ignore
    */
  function getTests(testClass){
    var testNames = new Array();
    for (var i in testClass) {
      name = i.toString();
      if(name.match("test")) testNames.push(name);
    } //for
    return testNames;
  } //getTests
}

Вот тут слегка поясню. От этого тест-сета мне нужны несколько свойств:
  1. Возможность добавлять тесты по одному. Очень полезная возможность, скажем на этапе дебага, или выборочного формирования набора для прогона. Для этого был сделан метод this.addTest.
  2. this.addTests метод уже служит для добавления всех тест методов какого-либо тест-класса. Для того, чтобы получить эти методы используется функция getTests. она пробегается по всем элементам класса (спасибо создателям JS за такую возможность) и выбирает методы, в имени которых есть "test". Это ограничение было введено, чтобы иметь возможность добавлять в классы какие-либо вспомогательные функции и быть уверенным, что они не будут распознаны как тесты.
  3. Возможность получить результаты прогона тест-набора.
Остальное, думаю тоже особо пояснять не надо. Разве что вот это this.addTest(testNames[i], testClass[testNames[i]](log));. Тут может быть интересна конструкция testClass[testNames[i]](log): во первых, эта строка собственно и вызывает i-й тест-метод, во-вторых по ее исполнения мы получаем результат выполнения теста.
Про параметр log можно пока не здумываться, я про это расскажу отдельно, он нужен, чтобы использовать кастомизированное логирование, но опять же, на данный момент это не важно, можете его хоть убрать, если сильно глаза режет :)


Собственно, это все, что я хотел рассказать на сегодня. Я уверен, что это решение можно сильно улучшить, но мне его хватает для того, чтобы нормально структурировать свои тест наборы и относительно прозрачно ими управлять.

Если улучшите, поделитесь, - будет повод написать о рефакторинге тестов :)

четверг, 10 ноября 2011 г.

Про маленькую Землю и самообман...

Недавно ко мне постучалась подруга и рассказала, что ee коллега нарыл блог про автоматизированное тестирование под iOS, "да вот только автор начал писать и забил, обидно так :) ".

Это вот про мой блог было... И если коллеге подруги было обидно, то мне стало стыдно, несмотря на то, что с формулировкой "забил" я бы не согласился, скорее отложил на "пока не появится больше времени" (я, однако, силен в самообмане:)

Скоро исправлюсь, обещаю!

среда, 6 апреля 2011 г.

UIAutomation. Начинаем.

Так, обзор пожеланий к тулам сделали, альтернативы посмотрели, даже про аджайл поговорили. Пора бы и честь знать начать бы и UIAutomation'ом пользоваться. Я планирую сейчас вкратце пробежаться по тому, как можно использовать UIAutomation "влоб" - как это задумал Apple. Так его использовать стоит далеко не всегда, но надо же с чего-то начинать.

Для начала неплохо бы этот инструмент иметь. Чтобы у вас завелся этот зверь, прийдется поставить XCode (среда разработки) с iOS SDK не ниже 4.0 - именно там он впервые появился. Последнюю версию можно взять тут, причем совершенно бесплатно, правда прийдется зарегистрироваться. Да, кстати, у Apple довольно интересная политика: инструменты они дают бесплатно, можете пользоваться, девелопить, тестить - на симуляторе. А вот чтобы собрать билд именно для девайса, - нужны сертификаты, и это уже за деньги. Впрочем, все это есть у них на сайте.

Итак, скачали, установили. Давайте пользоваться: запускаем Instruments, причем именно Instruments, а не UIAutomation. Просто Apple дает сразу кучу тулов, объединенных, скажем так, в один пакет, и UIAutomation - один из них. В общем, не суть, - возвращаемся к запуску. Если вы ничего не меняли в путях установки, то лежать эти самые Instruments будут по адресу /Developer/Applications/Instruments.app. Нашли? Запускаем, ждем... Открыться должно вот такое:


Выбираем категорию - в данном случае iOS Simulator, т.к. я хоть и работаю под девайсом, но показывать буду именно на симуляторе. В принципе, не суть важно, что вы выберете, различий все равно в результате не будет - под что автоматизировать, вы всегда можете перевыбрать.  Теперь кликаем шаблон Automation'a и получаем желаемый инструмент:

Это был стандартный шаблон, соответственно у вас в нем будут все (а их не так и много) настройки по умолчанию, а в моем случае, - уже те, которые были при последнем использовании. В частности у меня уже установлена папка, в которую будут складываться результаты.

Теперь нам нужно указать, что же именно мы будем тестить. Для этого нажимаем кнопку Choose Target и указываем сначала девайс. Мы будем запускать тесты на симуляторе, следовательно в качестве девайса выбираем свой компьютер:
Вариант "iPhone 12 (v4.2.1)" здесь присутствует потому, что у меня к компьютеру шнурком подключен айфон с iOS 4.2.1.

После выбора устройства идем в пункт меню Choose Target, который находится чуть ниже, и указываем приложение *.app, которое мы предварительно собрали для симулятора (если не собрали - собираем, так как очень сложно тестировать то, чего нет :), причем собираем исключительно в Debug режиме, иначе UIAutomation не сможет с ним работать. Собственно говоря, я для этого поста собрал самое простое приложение, оно абсолютно пустое, но для демонстрации вполне пригодно:

Если бы мы хотели тестировать приложение на iPhone, то принцип выбора приложения был бы примерно тем же: мы выбрали бы в качестве целевого устройства требуемый iPhone и указали бы приложение, на нем установленное. Да, кстати, тут есть несколько важных моментов: во-первых девайс должен непременно быть подключен шнурком к тому компьютеру, на котором будет запускаться UIAutomation, во-вторых, приложение уже должно быть установлено на девайс (UIAutomation умеет сходу ставить и запускать приложения только под симулятором, под девайсом - только запускать уже установленные), и в третьих, еще раз повторю, что тестировать можно только приложение, собранное под Debug. 

Так, приложение мы выбрали, осталось указать папку для хранения результатов тестовых прогонов (это делается в разделе Logging, см. слева внизу) и файл с тестовыми скриптами. На самом деле UIAutomation умеет запускать скрипты только из одного файла за раз. Как это обойти я покажу позже, а пока давайте просто создадим наш первый скрипт:
//Пишем в лог сообщение о начате тестинга 
UIALogger.logMessage("The test startet."); 
//получаем и пишем в лог дерево всех UI элементов приложения 
UIATarget.localTarget().frontMostApp().logElementTree(); 
//Собственно, все :) 
UIALogger.logMessage("The test finished.");
В этом куске кода можно подозревать чуть не любой язык, но это JavaScript. Здесь хочется особо отметить строку, в которой мы выводим в лог дерево объектов приложения, т.к. это главный способ получения информации о контролах в UIAutomation.

В общем, сохраняем этот код под любым именем и указываем его в окне UIAutomation в разделе Script. Теперь можно запускать выполнение. Для этого либо идем в меню и кликаем на пункте Run, или нажимаем на круглую кнопку с надписью, как это ни странно, Record (Apple, что с них взять). Вот так выглядит окно UIAutomation после выполнения нашего теста:
Да, чуть не забыл, останавливать выполнение тестов надо тоже вручную, иначе этот чудный инструмент будет думать, что он еще тестит :) Эта проблема тоже обходится, хоть и не сильно красиво. Про это будет, надеюсь, отдельный пост.

В принципе, это все, осталось только сказать, что в результате прогона мы получаем файл с результатами Automation Results.plist, который лежит в папке Run 1 (или Run 2, если вы запустите тест второй раз), которая в свою очередь лежит там, где вы сказали хранить результаты. Я не нашел способа указывать этому файлу другое имя, если найдете - поделитесь.
По сути, это xml-файл, так что обрабатывать его можно вполне цивилизованно, а можно и не обрабатывать, решать вам :)

На этом я пост закончу, дальше будут еще посты про этот инструмент и в этих постах я буду рассказывать про проблемы с UIAutomation и про пути их решения более подробно.