2/16/2014

Page Object Pattern для Cucumber/Capybara - как это работает



Page Object Pattern предполагает использование класса-посредника между пользовательским интерфейсом страницы и тестами, работающими с этим интерфейсом.
Для реализации патерна нет необходимости устанавливать дополнительные гемы и прочие тулзы. Безусловно, существует масса гемов, которые помогают в реализации Page Object, но это совершенно другая история…
В моем случае был использован
Cucumber v.1.3.10 с Capybara v.2.2.0 и с Rails (4.0.2)
В папку features необходимо добавить папку pages, в которой будут находится все ваши страницы с реализациями. Остальное дерево файлов остается без изменений.
Рассмотрим на примере сценария для Cucumber. Обычно описание шага выглядит так:

# features/step_definitions/user_steps.rb
1
2
3
4
5
6
7
Given /^I login with username "educator" and password "password"$/ do |username, password|
visit path_to('the home page')
find("#signin .signin").click
fill_in "login", with => username
fill_in "password", with => password
find("#loginPopover").find_button("Sign In").click
end
С помощью Page Object мы можем "скрыть" весь UI страницы и действия с ним за интерфейсом класса.

# features/step_definitions/user_steps.rb
1
2
3
4
5
Given /^I login with username "educator" and password "password"$/ do |username, password|
login_page = LoginPage.new
login_page.open_page
login_page.login(username, password)
end
Таким образом, мы скрыли детали реализации UI. Код класса LoginPage выглядит так:
# features/pages/login_page.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
class LoginPage
include Capybara::DSL

def login(username, password)
page.find('#user_login').set(username)
page.find('#user_password').set(password)
page.find('button.btn').click
end

def open_page
page.visit('/users/sign_in')
end
end
Количество методов в классе будет увеличиваться в зависимости от покрываемого функицонала. Так можно добавить еще один метод, который будет проверять залогинился ли пользователь.
# features/step_definitions/user_steps.rb
1
2
3
4
Given /^And I should see authorization status "message"$/) do |message|
login_page = LoginPage.new
login_page.check_authorization(message)
end
В класс LoginPage необходимо добавить метод check_authorization. После чего он будет выглядеть следующим образом:
# features/pages/login_page.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class LoginPage
include Capybara::DSL
def login(username, password)
page.find('#user_login').set(username)
page.find('#user_password').set(password)
page.find('button.btn').click
end
def open_page
page.visit('/users/sign_in')
end
def check_authorization(message)
case message
when 'correct'
within('.user-block') do
page.has_content?('.avatar-wrapper')
end
else 'incorrect'
within('.login-block') do
page.has_content?('.sign-form')
end
end
end
end
Что нам дает Page Object:
  • простой и читаемый DSL
  • при изменении UI нам будет достаточно только поменять класс относящийся к изменившейся странице. Сами тесты останутся без изменений.
Похожую реализацию можно использовать с помощью хелперов, но данынй подход мне показался более структурированным и удобочитаемым.

Комментариев нет:

Отправить комментарий