воскресенье, 27 апреля 2014 г.

Немного о собственном фреймворке

Начну с поклона Алексею Баранцеву, с его тренингом "Программирование для тестировщиков".

Благодаря его прохождению, к началу работы у меня было представление как собрать фреймворк для автоматизации тестирования с нуля, из бесплатных инструменотв.

Испорчу рекламный эффект: тренинг проходила N лет назад, нынче в сети больше информации на эту тему, и приобрести навык можно без таких затрат.

Исправлюсь: зато во время тренинга за вами проверят ДЗ, ответят на все вопросы на консультации и все такое прочее. 

Это я к чему? К тому, что выбор инструментов и технологий обусловлен только причинами "так было на тренинге" и "это бесплатный инструмент":

  • Java + TestNG + Selenium (который быстро был заменен на WebDriver)
  • Eclipse

Риторические вопросы

Какой он, мир автотестов на Python? А вот если бы JUnit? А вот Idea была бы удобнее?
Экспериментировать пока не собираюсь.

Что у меня работает

Тесты независимы. Тесты отделены от описания локаторов. Не уверена, укладывается ли это в рамки шаблона Page Objects (тм). Но дух "мухи отдельно, котлеты отдельно" соблюден.

Класс ScrEle - обертка вокруг вебдрайвера.

Содержит методы типа click, type и т.п. 
скриншот
рис 1. класс ScrEle - обертка вокруг вебдрайвера
Если я захочу работать с кнопкой OK, я должна где-то описать ее как ScrEle, указав в качестве параметра - локатор.  А потом вызывать нужные методы объекта.

NB Объект вебдрайвера нужно передавать каждому методу как параметр исключительно в силу моего нубства.

Классы страницы/формы

скриншот
рис 2. класс описывающий форму логина
Здесь описаны как элементы на странице -объекты ScrEle, так и методы для стандартных последовательности действий на странице.

NB Объект вебдрайвера нужно передавать каждому методу как параметр исключительно в силу моего нубства.

Тесты

рис 3. тест
В классе из примера заведен метод с последовательностью действий, каждый тест дергает его с разными параметрами.

Если мы не делаем одно и то же с разными параметрами - вся логика будет с методе с аннотацией @Test, доп. метод не понадобится.

Масштабы бедствия

  • реализовано около 50 тестов
  • время выполнения - около 15 минут
  • ручное выполнение тестов занимало бы 5 часов
  • тесты проверяют отчеты, сами не меняют данные в системе. данные в систему внесены предварительно
  • создать новый тест - недолго. создать данные для него - до нескольких часов 
  • 4% ложноотрицательных результатов, причина "не получилось кликнуть" - об этом расскажу подробнее
  • такой ложный fail в логе легко отличим от реального, тест можно быстро перезапустить

Чего остро не хватает

  • 5 часов ручной регрессии уже превращены в 15 минут работы автоматики. Но осталось еще около 15 часов регрессии. Есть куда расширять покрытие.
    • часть грядущих тестов будут аналогичны существующим: вся трудоемкость в заготовке тестовых данных
    • часть будет активно изменять данные. CUD и все такое. тут мне нужно понимание, в какой среде их запускать чтобы были независимыми и "убирали за собой"
Это - todo на ближайшее время, причем рабочее.

Чуть менее остро не хватает

  • Многопоточности.
  • Не все ок со стабильностью.
  • Очень раздражают стандартные отчеты. От того, что видела в thucydides, просто слюнки текут.

Шаблон проектирования Singletone

Ну и стыдное: драйвер инициализируется в родительском классе теста, и передается как параметр через все слои до самого нижнего, ScrEle...  Вроде жить не мешает, но неаккуратно выглядит. 2 недели назад узнала слово "синглтон", надо бы переделать.
скриншот
рис 4. мой маленький позор

Хочу чтобы строка
sTabReports.clientFuture.click(driver);
превратилась в 
sTabReports.clientFuture.click();

Аналогичный образом попробую избавиться от инициализации элементов UI в тестах:
STabReports sTabReports = new STabReports()
 ...пусть будет вынесено за кулисы, а не вызывается в самом тесте.

Тогда все объекты, описывающие UI будут инициализироваться всегда - а не строго перед тем как они понадобятся. Не очень экономно - но думаю не приведет к замедлению тестов. Если приведет, замечу.