пятница, 22 февраля 2013 г.

PageObject for PHP

Думаю нет нужды рассказывать про паттерн PageObject и  то как он реализован в байндингах для Java, C# и других языков.

Сегодня я расскажу как реализовать его на PHP. Вы скажите что для PHP есть множество версий клиента и универсальный паттерн будет сделать тяжело... Нет не тяжело скажу я вам.

Нужно просто использовать возможности языка и среды разработки.

Итак приступим:

<php
  /**
  * описываем тут наши элементы из массива чтоб среда разработки о них знала
  * @property element1
  * @property element2
  */
  class SimplePage{
  
  //наш драйвер, не важно из какого клиента
  protected $driver;
  
  // конструктор
  public __construct($driver){
    $this->driver=$driver;
  }
  
  //собственно элементы на стрнаице в виде массива
  private $elements=array(
                                         "element1"=>"//xpath1",
                                         "element2"=>"//xpath2",
                                        );
  
 //начинается магия
 public function __get($name){
   if (array_key_exists($name, $this->elements)){
     // каюсь тут уже придется использовать конкретный код из клиента
     // в нашем случае отсюда https://github.com/voodoo144/PHP-WebDriver
     return $this->driver->findElement(By::xPath($this->elements[$name]));
   }
 }

  }


Пример использования:

$page = new SimplePage($driver);
$page->element1; //вернет WebElement c xpath1
$page->element2; //вернет WebElement c xpath2


Надеюсь код получисля довольно очевидным. И если честно мне он нравится намного больше чем версия для Java.

вторник, 12 февраля 2013 г.

Почему скриптовые языки лучше для автоматизации?

Вопрос в заголовке - это скорее вопрос к пользователям и к самому себе.
С недавних пор перешел с Java на PHP... и понял насколько тяжеловесным был код тестов на java и как тяжело они писались и отлаживались по сравнению с ними-же на PHP.

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

Почему я думаю что скриптовые языки лучше:

1. Отсутствует избыточность синтаксиса
2. У динамических языков более широкие возможности для организации кода, нежели у статических. (замыкания, трейты, лямбда-функции)
3. Легкость чтения кода (тут конечно можно поспорить...)

Современная автоматизация web-приложений

Данная статья за моим авторством была опубликована в журнале "Tester's Life" в декабрьском выпуске.

Выложить статью для всех кто не видел журнал руки дошли только сейчас...

Современная автоматизация веб-приложений.
Автоматизированный тест – это скрипт или программа, которая имитирует взаимодействия пользователя с приложением для нахождения дефектов в приложении. Данное определение справедливо пожалуй только для GUI тестирования.
К авто-тестам также можно отнести и модульное тестирование — процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы.

В современном мире автоматизация тестирования все чаще используется при разработке программного обеспечения. С появлением множества методик и инструментов автоматизация выходит на новый уровень своего развития.

Прошлое автоматизации
На сегодняшний день автоматизация тестирования завоевывает все большую популярность. Множество компаний наконец-то усматривают в автоматизации больше плюсов, нежели минусов. Но так было не всегда.
Первые упоминания об автоматизации тестирования относятся к 70 годам двадцатого века, их можно найти в книге Фредерика Брукса «Мифический человеко-месяц или Как создаются программные системы». В данной книге речь в первую очередь шла о модульном тестировании.

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

Данный тип автоматизации прошел несколько этапов своего становления:

  1. Утилиты записи и воспроизведения (capture/playback tools) записывают действия тестировщика во время ручного тестирования. Они позволяют выполнять тесты без прямого участия человека в течение продолжительного времени, значительно увеличивая продуктивность и устраняя «тупое» повторение однообразных действий во время ручного тестирования. В то же время, любое малое изменение тестируемого ПО требует перезаписи ручных тестов. Поэтому это первое поколение инструментов не эффективно и не масштабируемо.
  2. Сценарии (Scripting) — форма программирования на языках, специально разработанных для автоматизации тестирования ПО — смягчает многие проблемы capture/playback tools. Но разработкой занимаются программисты высокого уровня, которые работают отдельно от тестировщиков, непосредственно запускающих тесты. К тому же скрипты более всего подходят для тестирования GUI и не могут быть внедренными, пакетными или вообще каким-либо образом объединены в систему. Наконец, изменения в тестируемом ПО требуют сложных изменений в соответствующих скриптах, и поддержка все возрастающей библиотеки тестирующих скриптов становится в конце концов непреодолимой задачей.
  3. Data-driven testing — методология, которая используется в автоматизации тестирования. Особенностью является то, что тестовые скрипты выполняются и верифицируются на основе данных, которые хранятся в центральном хранилище данных или БД. Роль БД могут выполнять ODBC-ресурсы, csv или xls файлы и т. д. Data-driven testing — это объединение нескольких взаимодействующих тестовых скриптов и их источников данных в фреймворк, используемый в методологии. В этом фреймворке переменные используются как для входных значений, так и для выходных проверочных значений: в тестовом скрипте обычно закодированы навигация по приложению, чтение источников данных, ведение логов тестирования. Таким образом, логика, которая будет выполнена в скрипте, также зависит от данных.
  4. Keyword-based - методология основанная на предпосылке что любые бизнес-события, представляющие каждое приложение, могут быть представлены в виде короткого текстового описания или ключевого слова и связанным с ним значением параметра. Например, большинство веб-приложений требуют от пользователя пройти аутентификацию, Ключевым словом для этого бизнес-события может быть "Logon User" и параметры могут быть "ID пользователя" и "Пароль". На этапе проектирования тестировщики  разрабатывают ключевые слова для описания отдельных функциональных бизнес-событий, тестировщики начинают строить общую библиотеку ключевых слов. Все слова из этой библиотеки могут быть использованы для создания тест-кейсов.

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

Про автоматизацию веб-приложений в то время речь вообще не заходила.
Во-первых не было утилит для такой автоматизации, а во-вторых не было веб-приложений. )))

Современная автоматизация веб-приложений
Интернет вошел в нашу жизнь давно и прочно. И различными веб-приложениями мы пользуемся не задумываясь. Все эти приложения нужно тестировать, плохо написанным и не оттестированным приложением пользоваться никто не будет, более того ошибки в таких приложениях могут привести к существенным проблемам у пользователей, и даже к потере денег.
Примером может служить любая система интернет-банкинга, каждый день миллионы пользователей через нее совершают различные платежи, открытие и закрытие счетов и другие операции с денежными средствами. Любая ошибка в таких системах недопустима, так как она может привести к потере денежных средств средств или даже к публикации приватных данных пользователя.

Сегодня многие компании начинают понимать все плюсы автоматизации тестирования, связано это с разрастанием программных продуктов и веб-приложений до невероятных размеров. Представьте что команде тестировщиков поручили протестировать сервис наподобии Yandex или Amazon, на одно только регрессионное тестирование могут уйти годы, так как функционал системы просто огромен. Компаниям требуется инструмент или методика, которая позволит увеличить покрытие тестами и сократит время на регрессионное тестирование.

Вот тут на сцену и выходит автоматизация. На сегодняшний день разработано огромное количество утилит и фреймворков, которые могут помочь тестировщикам автоматизировать процесс тестирования. Приведу лишь краткий список:
  • Selenium
  • Watir
  • Watij
  • Watin
  • phpBrowser
  • Geb
  • ZombieJS
  • PhantomJS
  • HtmlUnit
  • Codeception
  • Thucydides
  • Siculi
И этих фреймворков с каждым годом становится все больше. Не случайно что в этом списке я привел только фреймворки, которые распространяются бесплатно, но также существует ряд проприетарных программных продуктов. При выборе инструмента для автоматизации компании необходимо оценить сколько потребуется сил на доработку бесплатного фреймворка, или же дешевле будет купить платное решение, так-же на решение компании оказывают влияние такие факторы как возможности масштабирования фреймворка, качество поддержки фреймворка со стороны разработчиков, наличие специалистов.

Фактически все бесплатные фреймворки можно разделил на 2 большие группы:
  1. Основанные на WebDriver
  2. “Самобытные”
Причем первых большинство. Почему так получается ? Все потому что WebDriver в ближайшее время станет де-факто и де-юро стандартом.

В W3C с лета этого года разрабатывается черновик WebDriver API. В современной автоматизации веб-приложений webdriver и производные от него утилиты и фреймворки занимают особое место, обусловлено это его простотой, доступность и легкостью освоения, плюс ко всему его имплементации есть на многих языках программирования, таких как Java, C#, Python, Ruby. Просто выбираете удобный язык и начинаете писать авто-тесты.
Конечно это не так просто, как может показаться на первый взгляд, нужно обладать хотя бы базовыми познаниями в области программирования, но в интернете достаточно общедоступных материалов для изучения и уроков по написанию тестов.

В подтверждение своих слов о легкости написания и понимания, приведу пример кода на Java, Ruby и Python.
Java:
public class Selenium2Example  {    public static void main(String[] args) {        WebDriver driver = new FirefoxDriver();        driver.get("http://www.google.com");        WebElement element = driver.findElement(By.name("q"));        element.sendKeys("Cheese!");        element.submit();        System.out.println("Page title is: " + driver.getTitle());        (new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {            public Boolean apply(WebDriver d) {                return d.getTitle().toLowerCase().startsWith("cheese!");            }        });        System.out.println("Page title is: " + driver.getTitle());        driver.quit();    }
}


Ruby:

driver = Selenium::WebDriver.for :firefoxdriver.get "http://google.com"element = driver.find_element :name => "q"element.send_keys "Cheese!"element.submitputs "Page title is #{driver.title}"wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait
.until { driver.title.downcase.start_with? "cheese!" }puts "Page title is #{driver.title}"driver.quit

Python:
driver = webdriver.Firefox()
driver
.get("http://www.google.com")
inputElement
= driver.find_element_by_name("q")
inputElement
.send_keys("Cheese!")
inputElement
.submit()print driver.titletry:
   WebDriverWait(driver,
10).until(lambda driver : driver.title.lower().startswith("cheese!"))
   
print driver.titlefinally:
   driver
.quit()

Как видно из приведенного кода все достаточно ясно и понятно.

Как уже говорилось выше сейчас существует множество паттернов и подходов к написанию тестов. Рассмотрим некоторые из них.

  1. BDD( behavior-driven development или разработка через поведение)
  2. Functional Decomposition
  3. Object-Driven
  4. Model-based
Теперь кратко о каждом.

BDD  – разработка, основанной на функционировании или поведении системы.

Как это выглядит ? Тесты в bdd-стиле представляются простыми историями вида:
“Я хочу сделать то-то..
Потом я ожидаю увидеть то-то..
И сделать то-то...

Очень похоже на обычные тест-кейс? В это простоте теста заключена огромная мощь, фактически вы пишите обычные тест-кейсы в виде историй... и все. после того как они написаны фреймворк для bdd запустит их и превратит в авто-тесты.
Фреймворков на текущий момент существует множество:
  • easyb
  • JBehave
  • Cucumber
  • Thucydides и множество других.
Пример истории на easyb:

description "This story is about sqrt optimisation algorithm"
narrative "this shows sqrt optimisation", {
as a "java developer"
i want "to know how sqrt optimisation works"
so that "that I can pass google interview"
}
before "init input and expected result",{
}
where "complete scenarios data",{
input = [[5, 10, -3, 17, 12, 1, -2, 13, -12], [5, 8, 13, 5, 21, 6, 3, 7, -2, 4, 8, 12]]
leftIndex = [2,3]
rightIndex = [5,10]
expectedSumm = [27,51]
}
scenario "find summ within two indexes #leftIndex and #rightIndex of the array #input",{
given "An Sqrt algorithm implementation",{
alg = new SqrtDecompositionSum(input.toArray(new int[0]))
}
when "calc sum between two indexes", {
actualSum = alg.calcSummBetween(leftIndex, rightIndex)
}
then "summ should be equal expected #expectedSumm", {
actualSum.shouldBe expectedSumm
}
}

Все эти фремворки легко оптимизируются для тестирования веб-приложений. Во многих из них уже из коробки есть поддержка Selenium/WebDriver. А в тех в которых ее нет она появится в ближайшем будущем.

Functional Decomposition или FDD - паттерн при использовании которого конечная система разбивается на ряд более мелких систем которые легче понять, программировать и поддерживать.
В настоящий момент декомпозицию относят к анти-паттернам и устаревшим техникам. Данный паттерн родился из опыта не объектно-ориентированных разработчиков в попытке перенести процедурные приложения на объектную основу.

Симптомы и последствия применения такого паттерна.


  • Классы с "функциональными" именами, такие как Calculate_Interest или Display_Table могут указывать на применение этого анти-паттерна.
  • Все атрибуты класса являются частными и используются только внутри класса.
  • Классы которые выполняют только одно действие, как функции.
  • Невероятно вырожденная архитектура, которая полностью не соответствует объектно-ориентированному подходу.
  • Абсолютно не используются объектно-ориентированные принципы, такие как наследование и полиморфизм. Это может быть чрезвычайно дорого в поддержке.
  • Нет возможности четко документировать или даже объяснить как работает система. Модель классов не несет никакого смысла.
  • Нет возможности когда либо повторно использовать код.
  • Разочарование и отчаяние со стороны тестеров. )

Паттерн был впервые представлен Майком Экройдом, практическим консультантов по программному обеспечению Motorola, в 1996 году.

Object Driven или тесты, управляемые объектами – это такой подход к автоматизации тестирования, при котором тестовые скрипты проектируются в виде классов, в которых реализуется логика работы с приложением. Такие скрипты легче создавать и поддерживать, так как в тест-кейсах используются лишь методы «высокого уровня», позволяя скрыть подробности реализации тех или иных действий. Данный паттерн активнее всего используется для разработки авто-тестов с использованием инструмента Selenium/WebDriver. Благодаря чему на свет появился еще один специфичный для веб-приложений паттерн - Page Objects.  В данном паттерне каждое состояние(страница, фрейм, слой, блок) веб-приложения описывается отдельным объектом. Для большей наглядности давайте рассмотрим сайт состоящий из двух страниц:
авторизации и регистрации. Каждую из этих страниц опишем с помощью Page Object’а, для описания я буду использовать некий псевдоязык ( очень похожий на Java).
 Объект страницы регистрации

public class RegistrationPage{
//элементы на странице
public Element sex;
public Element username;
public Element password;
public Element email;

//методы для работы
public void open(){ //// описание метода }
public void register(username,password,sex,email){ //// описание метода}
public void getTitle(){//// описание метода}
}

Объект страницы логина

public class LoginPage{
//элементы на странице
public Element username;
public Element password;

//методы для работы
public void open(){ //// описание метода }
public void login(username,password){ //// описание метода}
public void getTitle(){//// описание метода}
}

Теперь, имея такие объекты, нам достаточно в тест-кейсе просто вызывать методы этих объектов.

@Test
public void test(){
RegistrationPage page=new RegistrationPage();
page.open();
page.register(“test”,”test123”,”male”,”test@example.com”);
assert(page.getTitle());
}

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

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

Приведу пример типичного workflow при таком подходе:


Более подробно о применении данной методики на практике можно прочитать в книге “Practical Model-Based Testing:A Tool Approach” by Mark Utting and Bruno Legeard.

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

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

Все эти возможности открывают перед тестировщиками- автоматизаторами доселе невиданные возможности в написании и выполнении тестов. Я верю что со времененм сервисов подобных SauceLabs будет появлятся все больше и больше.