Блог компании WapStart / Page Object — путь к совершенным автотестам

в 12:43, , рубрики: PageObject, qa, rspec, ruby, selenium-webdriver, wapstart, автоматизация тестирования

Блог компании WapStart / Page Object — путь к совершенным автотестам

Всем, доброго времени суток!
Этот топик о том как мы тестируем веб-интерфейс нашего продукта Plus1 WapStart. Мы используем Page Object, т.к. этот паттерн имеет много общего с реальными задачами и позволяет писать автотесты простыми для чтения и понимания.

Что такое Page Object

Page Object — это паттерн для реализации умных автоматических проверок. Gem page-object является имплементацией этого паттерна, который помогает в создании гибких страниц с объектами для тестирования браузерных приложений. Суть в том, чтобы создавать уровни абстракции для отделения тестов от предметов тестирования, и обеспечить простой интерфейс для элементов на странице. Gem работает с watir-webdriver и selenium-webdriver.

Установка Ruby и gems

Установим RVM:

$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

Для запуска примеров понадобиться последняя версия Ruby и gems:

$ rvm reload $ rvm install ruby-1.9.3-p125 $ rvm gemset create page-object && rvm use ruby-1.9.3-p125@page-object $ gem install rake page-object 

Hello, Page Object!

Создаем RegistrationPage для страницы регистрации — для этого включаем модуль PageObject, указываем адрес страницы и описываем элементы:

class RegistrationPage    include PageObject     page_url "http://www.passport.wapstart.ru/registration/"     text_field(:email, :name => 'mail')    text_field(:password, :id => 'hidden-password')    select_list(:source, :name => 'informationSource')    checkbox(:agreement, :name => 'agreement')    button(:register, :name => "register") end

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

DEFAULT_DATA = {    'email' => 'habrahabr@gmail.com',    'password' => 'qwerty',    'source' => 'Прочитал статью, новость о WapStart' 		  }

Создаем метод для заполнения только обязательных полей:

def default(data = {})    data = DEFAULT_DATA.merge(data)    self.email = data['email']    self.password = data['password']    self.source = data['source']    check_agreement    register end

Все базовые page objects определены, используем их в автотесте. Выберем драйвер selenium-webdriver, передав его в конструктор PageObject:

browser = Selenium::WebDriver.for :ff registration_page = RegistrationPage.new(browser, true) registration_page.default

Аргумент true открывает page_url, если мы попадаем на эту страницу кликом по ссылке, то его можно не передавать. Запустим пример:

$ ruby tests/RegisterDefault.rb

Таким образом в автотестах уходим от использования find_element и локаторов, код легко читаемый и повторно используемый.

Динамическая генерация методов доступа к элементам страницы

Accessors — методы класса, добавленные на страницу, подключением модуля PageObject. Методы генерируют еще один набор методов, которые обеспечивают доступ к элементам веб-страницы:
Блог компании WapStart / Page Object — путь к совершенным автотестам

Пример полностью описанной страницы регистрации:

require 'page-object' require 'selenium/webdriver'  class RegistrationPage    include PageObject     page_url "http://www.passport.wapstart.ru/registration/"     DEFAULT_DATA = { 	'email' => 'habrahabr@gmail.com', 	'password' => 'qwerty', 	'source' => 'Прочитал статью, новость о WapStart' 		    }     text_field(:email, :name => 'mail')    text_field(:password, :id => 'hidden-password')    checkbox(:showPassword, :id => 'showPassword')    select_list(:source, :name => 'informationSource')    text_field(:fio, :name => 'fio')    text_field(:phone, :name => 'phone')    select_list(:purpose, :name => 'registrationPurpose')    checkbox(:haveCode, :id => 'havePartnerCode')    text_field(:code, :id => 'plus1PartnerCode')    checkbox(:agreement, :name => 'agreement')    button(:register, :name => "register")     # Exception    span(:errorCode, :xpath => "//form[@id='registrationForm']/table/tbody/tr[9]/td[2]/span/span[2]")     def default(data = {})        data = DEFAULT_DATA.merge(data)        self.email = data['email']        self.password = data['password']        self.source = data['source']        check_agreement        register    end end

Пример автотеста для проверки валидности партнерского кода:

describe "RegisterUser" do    let(:browser) { @browser ||= Selenium::WebDriver.for :ff }  #Initialize new instance of Browser(driver)     it "InvalidCode" do        page = RegistrationPage.new(browser, true)        page.email = 'habrahabr@gmail.com'        page.password = 'qwerty'        page.source = 'Прочитал статью, новость о WapStart'        page.check_haveCode        page.code = 12345678        page.check_agreement        page.register        page.errorCode?.should be_true    end     after { browser.close } end

Примеры доступны на GitHub:

$ git clone git@github.com:ivaravko/pageobject-example.git $ cd pageobject-example/ pageobject-example$ rake

Открытие страницы из другой страницы

В большом проекте много страниц и они связаны между собой, для того чтобы выполнять переход добавим следующий шаг в default метод класса RegistrationPage — LoginPage.new(browser, true). Это позволит перейти на страницу ввода логина и пароля, не изменяя автотест.

def default(data = {})    data = DEFAULT_DATA.merge(data)    self.email = data['email']    self.password = data['password']    self.source = data['source']    check_agreement    register    LoginPage.new(browser, true) end

Автор статьи ivaravko

Ссылки

Блог автора гема
Страница на GitHub
Документация
Автор:

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


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