вторник, 22 октября 2013 г.

Что же делает QA/QC?


Вдогонку к заблуждениям. QC - это не поиск только багов, как уже говорилось ранее, это - предоставление полной информации о состоянии проекта. Сколько раз я читала эту фразу, но только сейчас она выкристализовалась в моем мозгу со всей своей ясностью - протестировать проект - это сделать его полное вскрытие и донести этот разрез до PM'а и/или разработчиков. И QC делает это вскрытие, а QA - показывает где и как резать, чтобы было лучше видно все детали.

пятница, 30 августа 2013 г.

Заметки на полях

Просто интересно - две компании, разработчики игр. На главных страницах - ВНЕЗАПНО - указана одна и та же игра, только у первых на мейле, у вторых - на одкл. С теми же...гм...ляпами. Нет, это не функционал (хотя я глубоко не копала), но в нашей фирме локализация поставлена так, что даже на банке с краской в арте вы не найдете следов английского текста. Т.е. у товарищей либо в куске движка остались англицизмы, либо это было портирование, поделенное между компаниями на 2 сети. Вторая интересная весчь - прикалываются они что ли - у обоих компаний открыты вакансии на QA (на сайтах с работой), но на сайтах собственных в перечне доступных вакансий - ВНЕЗАПНО! - ни у одной компании нет вакансии для QA. Это типа мы так пытаемся сразу определить насколько кандидат пошарился по сайту и нашел "баг" или просто несколько неактуальное состояние вакансий на сайте? У одних есть форма обратной связи - спросила интереса ради почему так - ответа нет. У второй компании даже формы обратной связи нет, только мыло - спрашивать лень. Но все равно интересно.
Еще наблюдизм - по ходу никто не отличает QA от QC - на всех сайтах с работой пишут QA, хотя по факту часто нужен QC. Если говорить о разнице, то QA это больше менеджмент (направление, постановка процесса для QC), а QC - практическая часть (тест-кейсы, выполнение, фиксация ошибок, проверки фиксов, пр). Такие хи-хи. UPD: они реально издеваются - еще одна контора, имеющая вакансию на сайте с работой, но которой нет на сайте (есть все, кроме как на тестировщика).

четверг, 22 августа 2013 г.

Большое заблуждение тестировщиков


Вот кто мне cкажет - что должен делать тестировщик? У 9/10 в голове всплывает "искать баги". Увы, это именно то, что хоронит проекты. Если тестировщик заинтересован только в поиске багов - пиши пропало. Если у него - после туевой хучи уебанных треннингов аля "Как найти удовольствие в работе? - Радоваться найденным багам!" - мозг настроен исключительно на поиск багов - проект либо вообще не будет выпущен, либо будет выпущен поздно (упущенная выгода + потеря лидирующих позиций) и все равно хромой. Поясняю на пальцах навожу порчу по IP - все знают, что программу невозможно полностью избавить от багов. Все знают, что если хорошенько искать - то найдется. А уж если речь идет о сложной программе, когда чиним уши - отваливается нос, то и подавно - багогенератор, точнее, эндорфиногенератов у вышеозначенных товарищей. Они не заинтересованы в затыкании фонтана своего удовольствия, а, следовательно, в выходе проекта. "Но что же тогда должен делать тестировщик?! Неужели пропускать баги, закрывать глаза на произвол?!" - в пылу воскликнет молодой и/или неопытный тестировщик. В первую очередь тестировщик должен уметь правильно расставлять приоритеты. Не у тикетов, нет, а в голове. "Насколько ломает игровой процесс этот баг? Сложен ли он в повторении? Реальна ли эта ситуация для пользователя? Сколько времени (читай - денег) может занять его починка?". Если это действительно важно - тикет. Если это может подождать до багфикса после выхода - запишите себе в отдельный список и не мучайте команду обновляющимися через каждые 5 минут тикетами. Конечно, не все эти вопросы тестировщик может решить сам - подойдите к PM'у - они не кусаются. Более того, именно PM лучше вас даст оценку - будет это чинится срочно или нет и будет в курсе всех проблем. И ваша совесть будет чиста - вы не просто умолчали, а доложили и приняли решение вместе (ваша задача для этого - дать PM'у понять всю полноту картины). Далее. Не нужно плодить кучу однородных тикетов - "тут съехал текст", "тут кривая кнопка", "тут вылез английский/китайский/афрояпонский текст" - сделайте один с пунктами и вы увидите, насколько вы облегчите собственную жизнь и жизнь программиста. Куда легче обновлять тикет пачкой, чинить и проверять, чем жонглировать 10 однотипными. Ну, про уточнение условий писано-переписано уже сто раз. Не пишите условия "шаг влево, шаг вправо - расстрел" - исследуйте вширь - только ли при таких условиях, а если чуть изменить/убрать шаг? Не пишите "тут сломалось, наверное в <аналогичное место> тоже поломано" - посмотрите бога ради в это аналогичное место! Чем больше информации вы дадите для починки, тем меньше времени уйдет на починку, ведь именно вы, а не программист работаете с клиентской частью, вы знаете ее куда лучше. И последнее - помните про приемочное тестирование - именно этим вы должны заниматься перед выходом проекта, а не поиском багов.
А радоваться надо не найденным багам, а починенным. Если вы радуетесь только найденным - получается, что вам совсем неважно? что ваш проект - хромой, убогий и болезный, да вы именно этому и рады. А если вы радуетесь починкам - значит, вы улучшаете качество вашего продукта, радуетесь его росту, улучшению.

вторник, 2 июля 2013 г.

Свой опыт с Genie

Итак, теперь, когда мы имеем немого представления об инструменте, я попытаюсь рассказать о своем опыте его использования. Что нужно, что бы записать простой скрипт с Geine? Запущенный сервер, Эклипс и зеленый треугольник UT на флешке (не забываем коннектиться к SWFке). Жмем на значок и запись скрипта пошла! При этом значок становится красным квадратом (ВНЕЗАПНО!), при нажатии на кортоый запись, соответственно, прекращается. Но об этом чуть позже.
Если перед записью скрипта мы выбрали в выпадающем меню пункт "Запись с тупняками" (Record Script At Application Pace),  то все задержки между кликами будут учтены в скрипте.  Запишем что-нибудь самое простецкое, закрытие входных pop-up'ов. Загружаем игру и когда появляется газета, запускаем запись. Покликали, закрыли и остановили. После остановки записи Джин любезно вываливает на окошко с телом скрипта и кнопками "скопировать" и "закрыть" - наше дело сохранить этот скрипт либо в файлик, либо пока прямо в панель Эклипса со скриптами. Получится примерно такое: 


package scripts;
import com.adobe.genie.genieCom.SWFApp;
import com.adobe.genie.executor.GenieScript;
import com.adobe.genie.executor.components.*;
import com.adobe.genie.executor.uiEvents.*;
import static com.adobe.genie.executor.GenieAssertion.*;
import com.adobe.genie.executor.enums.GenieLogEnums;

/**
 * This is a sample Genie script.
 *
//Change name of the class
public class Unnamed extends GenieScript {

public Unnamed() throws Exception

super();
}

@Override
public void start() throws Exception {
//Turn this on if you want script to exit
//when a step fails
EXIT_ON_FAILURE = false;
//Turn this on if you want a screenshot
//to be captured on a step failure
CAPTURE_SCREENSHOT_ON_FAILURE = false;

SWFApp app1=connectToApp("[object Preloader]");
(new GenieDisplayObject("SP^NewspaperPopup:::FP^NEWSPAPER:::SE^closeBtn::PX^0::PTR^0::IX^9::ITR^0",app1)).click(7,11,704,60,0,0,3,false);
(new GenieMovieClip("SP^MessageWindow:::FP^CloseButton:::SE^htmc::PX^25::PTR^0::IX^1::ITR^0",app1)).click(27,18,740,22,0,0,3,true);
}
}

где выделенны маркером те самые Genie ID и после них команда click (). Если аргументы click оставлять пустыми, то нажатие будет выполнено без подведения курсора на элемент. Теперь для того, чтобы запустить наш скрипт, нам понадобится сбросить его в текстовый файлик, обозвать его xxx.java (где xxx должен быть такой же, как и Unnamed - не забыть задать имя в теле скрипта), открыть в эклипсе. Если есть ошибки, редактор эклипса их выделит (в готовом скрипте ошибок конечно нет, но при модификации мы вполне можем что-нибудь напортачить). Следующий этап запуска - выбрать пункт Run Configuration... и в открывшемся окне в пункте New configuration во вкладке Arguments в доме, который построил Джек  строке Program Arguments указать перед .class имя скрипта (оно же имя из public class Unnamed extends GenieScript и
{
public Unnamed() throws Exception:

Т.е. если у меня скрипт называется MC, но и в теле скрипта тоже стоит MC и в классе тоже MC. Возможно, для программистов это очевидно, но я в этом объезьяна, как сказали, как написано в документе, так и описываю :) После этого кликаем Run и переходим к нашей флешке. Во время выполнения скрипта значок на SWFке вверху меняется на красный треугольник без фона.
Как видно, сам кусочек с кликами занимает всего ничего - закрыли пару окон, получили пару строчек. Но это если нам нужно сделать всего пару действий, при более сложных задачах конечно конструкции становятся сложнее. К примеру, скрипт на прохождение HOG-сцены включал в себя считывание текста с плашки, сопоставление текста с соответствующим ему объектом и клик уже непосредственно по идентифицированному объекту. Предметов в HOGe у нас от 60 до 75, для каждой сцены приходилось делать такие библиотеки со связками "текст-объект". И тем не менее, скрипт работает! Если бы получилось таки добить остальные куски и соединить их в комплект, у меня был тест, выполняющий максимальное покрытие вширь функционала за минимальное время. Подозреваю, что на этапе соединения тоже были бы свои проблемы, но увы, опыта в этом деле мне обрести пока не удалось. 

четверг, 27 июня 2013 г.

Genie, основные элементы

UPD: великодушно простите что скрины протухли
Обманула - перед тем, как начать разбираться со скриптами, нам нужно научиться работать с основными элементами, чем мы и займемся.
Итак, мы подняли Genie у себя и запустили эклипс с соответствующим плагином. А дальше? Рассмотрим основные элементы и что умеет наш Джин.
Для начала, чтобы можно было сразу проверять элементы в действии, законнектимся к нашей  SWFке (предварительно запущенной в браузере) - названия в списке могу быть другими, но это ваша SWF

После коннекта мы получим дерево с объектами, а в таблице ниже будут свойства выбранного и, самое важное, genieID - тот самый уникальный идентификатор для каждого (!) объекта.

К объекту можно обращаться через этот идентификатор. Свойства (Property) могут не показывать последнее состояние приложения, однако их можно вызвать - это будет освещено позже.
Итак, мы в коннекте с нашей SWF, видим дерево объектов. Но как в этом дереве найти нужный нам объект? Для этого рассмотрим панельку [тут был скрин, простите, гугл его скушал]
Начнем со значка Лупа. Именно этот элемент позволит нам, кликнув на объекте в SWF, увидеть его в дереве. У этого значка есть два состояния (помимо выключенного):
[тут был скрин, простите, гугл его скушал]
Первое - обычное - позволит найти объект и провзаимодействовать с ним (скликнуть). Второе:
[тут был скрин, простите, гугл его скушал]
кликнет на объект, но без взаимодействия - оно нужно, если вам нужно найти его в дереве, но не скликивать из рабочей области. К примеру, в HOG сцене ( (Hidden Object Game - игры, где на картинке нужно найти заданные объекты) мне нужен ID элемента, но если я кликну на него с взаимодействием (первое состояние), то объект будет отмечен как найденный и просто "уйдет" со сцены, что, мягко говоря, неудобно, если с ним требуется дальнейшая работа. В этом случае второе состояние поиска просто незаменимо. Третье нажатие на Лупу отключит поиск.
Кисточка позволит нам подстветить в SWF выбранный в дереве объект. Просто выделите объект, кликните на кисточку и в SWF вы увидите, что он выделился красным контуром:
[тут был скрин, простите, гугл его скушал]
Линейка позволит получить локальные координаты выбранного объекта. Честно говоря, не пользовалась и в моем случае координаты - не совсем то, к чему хотелось бы привязываться, но все равно круто. Панель с координатами появится в SWF прямо под значком Genie, водите по объектам, а в панельке показываются цифры.
Камера делает скриншот, через который тоже можно будет обратиться к элементу, указав путь и степень толерантности (точность совпадения, с которой будет сравниваться указанный рисунок с искомым на экране - от 0 до 100, чем ниже толерантность, тем точнее Genie будет пытаться определить объект). Эта функция очень удобна, если вдруг в игре или на экране имеется HTMLный элемент, к которому необходимо обратиться. Нужно отметить, что не стоит увлекаться чрезмерной точностью совпадения - при достаточно высокой толерантности Джин может просто не найти объект, соотвественно, при низкой - кликнуть не на тот, что нам нужен. Область скриншота лучше брать с захватом побольше - выше вероятность, что будет кликнут именно указанный, а не похожий объект. Как пользоваться камерой: жмем на значок, затемняется область и появляется крестик, выделяем нужную нам область и после отжатия клавиши мыши будет показано окно с рисунком и кнопками:

Сохранить понятно что делает, Recapture переснимает, с закрытием тоже понятно, а Add Hotspot добавляет на рисунок область, непосредственно в которую будет сделан клик. Т.е. по умолчанию клик буден сделан в центр, но если нам нужно кликнуть на кнопку, которая на рисунке не в центре, то просто задаем "горячую точку" и можем не беспокоится.
Добавить в скрипт клик на указанный рисунок можно используя класс функций Com.adobe.genie.executor.uiEvents.UIImage, например:
new UIImage().clickImage(String imagePath , int… tolerance) 
new UIImage ().clickImageHotspot (String imagePath , int… tolerance)
Запросить свойства объекта (Request Genie Properties of Object) вот та функция, которая пригодится нам в случае, когда просто Property не показывают последние изменения в SWF. К примеру, у меня меняется плашка в SWF, а Genie в свойствах показывает старый текст, нажимаем "Запросить свойства объекта" и получаем развернутый список, где поле text уже обновлено и содержит текущий текст.
Обновить дерево объектов - ну тут понятно, обновляется дерево, однако иногда это не помогает получить обновленные свойства и их нужно запрашивать предыдущей кнопкой.
И наконец несколько пунктов, которые не вынесены на панель, а появляются по клику на стрелочку [тут был скрин, простите, гугл его скушал]
Hide Genie Icon убирает значок  UT с флешки (иногда здорово мешает), минус в том, что только на время пока запущен Эклипс. Впрочем, иногда в разных браузерах значок сам отваливается.
Record Script At Application Pace скрипт будет записан с простоями, т.е. ваши паузы будут учтены в виде wait'ов
Disconect SWF с этим все ясно, отсоединиться от флешки.
Find component by GenieID тоже не требует особых пояснений.
Save Tree XML in File ясно что делает, но у меня не открылось сохраненное дерево, увы. Может кто-то лучше меня разбирается что с этим потом делать, поделитесь.
Вот, собственно, все функции Джина и их с головой достаточно чтобы сделать что-то удобоваримое. К сожалению, на проекте урезали бюджет и я пока не занимаюсь дальнейшей автоматизацией, все что у меня получилось - несколько тестов, не соединенных в слитный комплект, но ни с одни инструментом кроме Джина мне не удавалось добиться даже такого результата: получилось сделать скрипт на прохождение HOG сцен (сцены с предметами, которые нужно найти на ней), делать оплаты (фейковые, с элементами HTML - вот где пригодилось распознавание картинок), пройти туториал. Вероятно, Джин можно использоваться в связке с селениумом, может получится плодотворное сотрудничество. Возможно, опробую на сайте с флешем, если таковой дадут погонять :)
UPD: вот тут как раз человечище связал таки Genie c Webdriver и TestNG, получилось удобно

четверг, 23 мая 2013 г.

Тадааам! Позвольте представить - Genie!

Automated UI Tester for Adobe® ActionScript® is code named as Genie.

Джин - вот то, что поможет нам в автоматизации тестирования флешевых приложений! Джин создан для флеша, не требует доступа к исходному коду или запуска внутри приложения и может запускаться в фоне (в отличии от Sikuli). Его отличительной способностью является умение однозначно определять любой элемент внутри флеша (epic win!). Можно записывать произведенные действия скриптами и запускать их! Правда, после доработки напильником, но по сравнению с тем же Sikuli (сразу оговорюсь, что ничего не имею против самой проги - она отлична и достойна похвал, но для флеша её ценность стремится к нулю) это просто песня.
Что нужно для его запуска? Сам Джин конечно же, Эклипс, дебажный флеш-плеер и немного усилий в продирании по англоязычному гайду.
Итак, начнем.
Тут http://sourceforge.net/adobe/genie/wiki2/FAQ/ как можно догадаться, FAQ. Квитэссенцию прелестей я изложила выше.
Там же можно нажать Files, чтобы перейти к документации и файлам http://sourceforge.net/projects/genie.adobe/files/
В документации есть pdfка UserGuide, в которой очень подробно и хорошо, но на английском. расписывается что к чему и почему. Я постараюсь на русском изложить все, что оттуда удалось выдрать. Сразу оговорюсь, что у меня Винда, а работает эта штука только в опере, хотя написано, что поддерживает все браузеры с флешем (и как раз опера там не указана). Т.е моя конфигурация - Windows 7, Opera.
Итак,
1. Скачать из директории с файлами архив Genie-binary.zip и распаковать его куда угодно.
2. Установить дебажный флеш-плеер, инструкция любезно прилагает ссылку для скачивания  http://www.adobe.com/support/flashplayer/downloads.html (разумеется, выберите подходящий для вашей оси и разрядности)
2. Установить Яву (JDK - Java Development Kit), тоже любезно прилагается ссылка 
3. Ну и поскольку Джин у нас является эклипсовым плагином, то конечно нужен Эклипс, скачать тут
Это все был подготовительный этап, начинается впилка.
4. Наш разархивированный Джин лежит себе на диске с путем [GeniunePath], и этот путь нам еще пригодится.
5. Копируем из нашего  [GeniunePath]\GeniePlugin файлик GeniePlugin.jar и закидываем его в папку с плагинами Эклипса, например D:\Eclipse\Plugins
6. Копируем также из [GeniunePath]\GenieLibrary файл mm.cfg в пользовательскую папку, т.е. C:\Documents and Settings\testuser\
7. Теперь открываем его в блокноте и правим путь к SWFке, должно получится так:
PreloadSWF = [GeniunePath]\GenieLibrary\GenieLibrary.swf (помним, что это шаблон пути, где обитает наш Джин)
8. Дальше шаманство - переходим по ссылке  и, выбрав "Добавить местоположение"

указываем путь к SWFке (это тот самый путь, что мы прописывали в mm.cfg) [GeniunePath]\GenieLibrary\GenieLibrary.swf - зачем это делается, написано в самом окошке. После добавления пути нужно отметить "Всегда разрешать" и просто закрыть это окно.
9. Запускаем сервер Джина (повторюсь, что я поднимала все под Виндой, поэтому понятия не имею что с остальными осями, у прогаммиста под никсом все встало, но Джин не коннектится к SWFке и толку от него получается ноль) из [GeniunePath]\GenieServer - там лежит батник LaunchServer.bat
10. Запускаем Эклипс. Чтобы вытащить наш плагин на свет божий (если он автоматом не подкинулся), выбираем Windows > Show View > Other > Genie > Genie. Рекомендую подглядывать в гайду, там годные скриншоты.
11. Запускаем браузер и в нем любую SWFку, у меня это флешевая игра (ради чего всё и затевалось). На ней теперь в левом верхнем углу должен появится значок Джина:
 . Он будет серым, если батник с сервером не запущен. 
И этот зеленый значок значит, что мы все подняли правильно! Первый этап пройден :) Не переключайтесь, в следующем посте я расскажу сама себе, вызывайте санитаров! как слабать простенький скрипт :)