рдкреГрд╖реНрда рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рддрдХрдиреАрдХреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдЕрдореВрд░реНрдд (рдЕрд▓рдЧрд╛рд╡) рдХреА рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╡рд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдпрд╛рдж рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рд╡реЗ (рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╕реНрдерд┐рд░рддрд╛ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдФрд░
DRY рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЦреБрдж рдХреЛ рджреЛрд╣рд░рд╛рдПрдВ рдирд╣реАрдВ) - рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ (рд╡реЗрдмрд╕рд╛рдЗрдЯ) рдХреЛ рд╕рд░рд▓ рддрд░реАрдХреЛрдВ рд╕реЗ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрдЯ рдХрд░рдХреЗред
рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ
рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИ (рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИ), рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реАрдХреЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИред
рд╢рдмреНрджрд╛рд╡рд▓реА
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рд╢рдмреНрдж рдмрд╣реБрдд рд╕рд╛рдорд╛рдиреНрдп рд╣реИред рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдореЗрдВ,
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдирд┐рдореНрди 3 рдкреНрд░рдХрд╛рд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:
- рдШрдЯрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдШрдЯрдХреЛрдВ рдпрд╛ рд╡рд┐рдЬреЗрдЯ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдЯреЗрдмрд▓, рдореЗрдиреВ, рд▓реЗрдЦ рдФрд░ рдЕрдиреНрдп рдмреНрд▓реЙрдХ рдЬрд┐рд╕рдореЗрдВ рдШрдЯрдХреЛрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣реЛрддрд╛ рд╣реИред
- рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рдХрдИ рдШрдЯрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рднреАрддрд░ рдирд┐рд╣рд┐рдд рдЕрдореВрд░реНрдд рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
- рдЕрдиреБрднрд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд╕рдореВрд╣реАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХрдИ рдЪрд░рдгреЛрдВ рдпрд╛ рдХрдИ рдкреГрд╖реНрдареЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╣рднрд╛рдЧрд┐рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЕрдиреБрднрд╡ рд╕реЗ, рдореИрдВрдиреЗ рдЗрд╕ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдПрдХ рдкреГрд╖реНрда рдкрд░ рдЬрдЯрд┐рд▓ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ (рд╢реИрдХреНрд╖рд┐рдХ рдкреГрд╖реНрдареЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг, рдПрдХ рдирдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдмрдирд╛рдирд╛, рдЖрджрд┐)
рдЙрджрд╛рд╣рд░рдг
рд╕рд░рд▓
RSpec Capybara рдкрд░реАрдХреНрд╖рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдЬреЛ рдмреНрд▓реЙрдЧ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:
require 'feature_helper' feature 'Blog management', type: :feature do scenario 'Successfully creating a new blog' do visit '/' click_on 'Form Examples' expect(page).to have_content('Create Blog') fill_in 'blog_title', with: 'My Blog Title' fill_in 'blog_text', with: 'My new blog text' click_on 'Save Blog' expect(page).to have_selector('.blog--show') expect(page).to have_content('My Blog Title') expect(page).to have_content('My new blog text') end scenario 'Entering no data' do visit '/' click_on 'Form Examples' expect(page).to have_content('Create Blog') click_on 'Save Blog' expect(page).to have_content('4 errors stopped this form being submitted') expect(page).to have_content("Title can't be blank") expect(page).to have_content("Text can't be blank") expect(page).to have_content('Title is too short') expect(page).to have_content('Text is too short') end end
рдЖрдЗрдП рдХреЛрдб рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ, рдЗрд╕рдореЗрдВ рдХрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд░рд┐рдпрд╛рдПрдВ рд╣реИрдВ: рд╕рдВрдмрдВрдзрд┐рдд рдкреГрд╖реНрда рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛, рдкреГрд╖реНрда рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдирд╛ рдФрд░ рд╕рд╛рдордЧреНрд░реА рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ред рдХреЛрдб рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣
DRY рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдкрд╛рд▓рди рдХрд░рдХреЗ рддрдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣ рд╕рдордЭрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреЗ рддрд╣рдд рдЖрд╡реЗрджрди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдиреЗ рдкрд░ рдЗрд╕ рдХреЛрдб рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рддрддреНрд╡ рд╡рд░реНрдЧ, рдирд╛рдо рдФрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреЗ рдирд┐рдпрдорд┐рдд рдЕрдкрдбреЗрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдЗрд╕ рдХреЛрдб рдореЗрдВ рднреА рдХреЛрдИ 'рд╕рд┐рдореЗрдВрдЯрд┐рдХ рд╕рдВрджрд░реНрдн' рдирд╣реАрдВ рд╣реИ, рдпрд╣ рд╕рдордЭрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ рдХрд┐ рдХреЛрдб рдХреА рдХреМрди рд╕реА рд▓рд╛рдЗрдиреЗрдВ рддрд╛рд░реНрдХрд┐рдХ рд░реВрдк рд╕реЗ рд╕рдореВрд╣рдмрджреНрдз рд╣реИрдВред
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкрд░рд┐рдЪрдп
рдЬреИрд╕рд╛ рдХрд┐ рд╢рдмреНрджрд╛рд╡рд▓реА рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╣реИ, рдкреНрд░рд╕реНрддреБрддрд┐-рд╕реНрддрд░ рдХреЗ рд╕рд╛рд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓реЗрддреЗ рд╣реБрдП рдФрд░ рдирдП рдмреНрд▓реЙрдЧ рдмрдирд╛рдиреЗ рдФрд░ рдмреНрд▓реЙрдЧ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдХреЛрдб рдХреЛ рд╕рд╛рдлрд╝ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рддрдХрдиреАрдХреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЬрд╛рдирдХрд╛рд░реА рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо (рдХреЛрдб) рдкрдврд╝рдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (рдЖрдИрдбреА, рд╕реАрдПрд╕рдПрд╕ рдХрдХреНрд╖рд╛рдПрдВ, рдЖрджрд┐) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
require 'feature_helper' require_relative '../pages/new_blog' require_relative '../pages/view_blog' feature 'Blog management', type: :feature do let(:new_blog_page) { ::Pages::NewBlog.new } let(:view_blog_page) { ::Pages::ViewBlog.new } before :each do new_blog_page.visit_location end scenario 'Successfully creating a new blog' do new_blog_page.create title: 'My Blog Title', text: 'My new blog text' expect(view_blog_page).to have_loaded expect(view_blog_page).to have_blog title: 'My Blog Title', text: 'My new blog text' end scenario 'Entering no data' do new_blog_page.create title: '', text: '' expect(view_blog_page).to_not have_loaded expect(new_blog_page).to have_errors "Title can't be blank", "Text can't be blank", "Title is too short", "Text is too short" end end
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдореЗрдВ рдкрд╣рд▓рд╛ рдХрджрдо рдПрдХ
рдореВрд▓ рдкреЗрдЬ рдХреНрд▓рд╛рд╕ рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдирд╛ рд╣реИ:
module Pages class NewBlog include RSpec::Matchers include Capybara::DSL
рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ (рд╕рдХреНрд╖рдо рдХрд░рдирд╛)
Capybara :: рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ
Capybara рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ
рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ
рд▓рд┐рдП DSL has_css? '.foo' has_content? 'hello world' find('.foo').click
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВрдиреЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛
RSpec :: рдорд╛рдЪрд┐рд╕ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ
рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ
рдЙрдореНрдореАрдж RSpec рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рд╕рдордЭреМрддреЗ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рди рдХрд░реЗрдВ,
рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ
рдЕрдкреЗрдХреНрд╖рд╛ (рдЕрдкреЗрдХреНрд╖рд╛рдПрдВ) рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЬрд╣рд╛рдБ рдЙрдкрдпреБрдХреНрдд рд╣реЛ, рдореИрдВ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП
рдХреИрдкрд┐рдмрд╛рд░рд╛ рдХреЗ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рддрдВрддреНрд░ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреЗрддрд╛ рд╣реВрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд
Capybara рдХреЛрдб
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рдЕрдВрджрд░
'foo' рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА
рдЙрдореНрдореАрдж рдХрд░реЗрдЧрд╛ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ,
рд╕реНрд╡рдпрдВ ):
expect(self).to have_content 'foo'
рд╣рд╛рд▓рд╛рдБрдХрд┐, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдореЗрдВ:
expect(page_object.content).to match 'foo'
рдЕрдирдкреЗрдХреНрд╖рд┐рдд рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╕рдВрднрд╡ рд╣реИрдВ (рдПрдХ рдлреНрд▓реЛрдЯрд┐рдВрдЧ рдЯреЗрд╕реНрдЯ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ), рдЪреВрдВрдХрд┐
рдкреЗрдЬ_рдмрдЬреЗрдХреНрдЯред рдХреЙрдиреНрдЯреЗрдВрдЯ рдХреЛ рд╕реНрдерд┐рддрд┐ рдХреЗ рдЕрдиреБрдкрд╛рд▓рди рдХреЗ рд▓рд┐рдП рддреБрд░рдВрдд рдЬрд╛рдВрдЪ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдЕрднреА рддрдХ рдШреЛрд╖рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдзрд┐рдХ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВ
рд╡рд┐рдЪрд╛рд░рд╢реАрд▓ рдХреЗ рд▓реЗрдЦрди рдХреЛ Capybara рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣
рджреВрдВрдЧрд╛ ред
рд╡рд┐рдзрд┐ рдирд┐рд░реНрдорд╛рдг
рд╣рдо рдЙрд╕ рд╕реНрдерд╛рди (рдХреНрд╖реЗрддреНрд░) рдХрд╛ рд╕рд╛рд░ (рд╡рд░реНрдгрди) рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдБ рд╕реЗ рд╣рдо рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
def visit_location visit '/blogs/new'
рдЖрдкрдХреЗ
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╢рдмреНрдж рдХрд╛
рд╕рд╣реА рдирд╛рдо рдЪреБрдирдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ
def create(title:, text:)
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдПрдХреАрдХреГрдд рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдФрд░ рдЬрд╣рд╛рдВ рд╕рдВрднрд╡ рд╣реЛ, рдПрдХрд▓ рдЬрд┐рдореНрдореЗрджрд╛рд░реА (рдПрдХрд▓ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕рд┐рджреНрдзрд╛рдВрдд) рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВред
рдШрдЯрдХ рд╡рд╕реНрддреБрдУрдВ
рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо NewBlog рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд╣реАрдВ рд╣реИред
рдЪреВрдВрдХрд┐ рд╣рдо рдлреЙрд░реНрдо рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕ рдШрдЯрдХ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдЧ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:
рдЬрд╣рд╛рдВ BlogForm рдХреЗ рд▓рд┐рдП рддрд░реАрдХреЗ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:
module Components class BlogForm include RSpec::Matchers include Capybara::DSL def create(title:, text:) within blog_form do fill_in 'blog_title', with: title fill_in 'blog_text', with: text click_on 'Save Blog' end end private def blog_form find('.blog--new') end end end
рд╕рдм рдПрдХ рд╕рд╛рде
рдЙрдкрд░реЛрдХреНрдд рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЕрдм рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд┐рд╡рд░рдг рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк
рдореЗрдВ рдЕрдкрдиреЗ
рдкреГрд╖реНрда рдХреА
рдкреГрд╖реНрда рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдХреНрд╡реЗрд░реА рдФрд░ рдЗрдВрд╕реНрдЯреЗрдВрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
require 'feature_helper' require_relative '../pages/new_blog' require_relative '../pages/view_blog' feature 'Blog management', type: :feature do let(:new_blog_page) { ::Pages::NewBlog.new } let(:view_blog_page) { ::Pages::ViewBlog.new }
рдиреЛрдЯ: рдореИрдВрдиреЗ рдЬрд╛рдирдмреВрдЭрдХрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдПрдХ рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рд╣реИред рдХреБрдЫ RSpec рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рд╕рднреА рд╕рдорд░реНрдерди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдЙрди рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреЛрдб рдХреЗ рдмрдбрд╝реЗ рдЯреБрдХрдбрд╝реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдЕрддреНрдпрдзрд┐рдХ рдХрд╛рд░реНрдпрднрд╛рд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдпрд╣ рдзреАрдореА рдЧрддрд┐ рд╕реЗ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдФрд░ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдирдкреЗрдХреНрд╖рд┐рдд рдЪрдХреНрд░реАрдп рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдЬрдиреНрдо рджреЗрдЧрд╛ред
рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ
рдЕрдм рдкреНрд░рддреНрдпреЗрдХ рдкрд░рд┐рджреГрд╢реНрдп рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕
new_blog_page рдФрд░
view_blog_page рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рд╣реЛрдЧреА:
scenario 'Successfully creating a new blog' do new_blog_page.create title: 'My Blog Title', text: 'My new blog text' expect(view_blog_page).to have_loaded expect(view_blog_page).to have_blog title: 'My Blog Title', text: 'My new blog text' end
рдирд╛рдордХрд░рдг рд╕рдореНрдореЗрд▓рдиреЛрдВ / рд╡рд┐рдзреЗрдп рд╡рд┐рдзрд┐рдпреЛрдВ
рд░реЗрд▓ / рд░реВрдмреА рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЪреАрдЬреЛрдВ рдХреЗ рд╕рд╛рде, рдРрд╕реЗ рд╕рдореНрдореЗрд▓рди рд╣реИрдВ рдЬреЛ рдПрдХ рдирдЬрд╝рд░ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдорд╣рддреНрд╡рд╣реАрди (рдмрд╛рдзреНрдпрдХрд╛рд░реА рдирд╣реАрдВ) рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рд╣рдордиреЗ
has_loaded рдФрд░
has_blog рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреА:
expect(view_blog_page).to have_loaded expect(view_blog_page).to have_blog title: 'My Blog Title', text: 'My new blog text'
рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╣рдорд╛рд░реЗ рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╡рд┐рдзрд┐ рдирд╛рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ
has_loaded рд╣реИ? рдФрд░
has_blog рд╣реИ? :
def has_loaded?
рдпрд╣ рдПрдХ рд╕реВрдХреНрд╖реНрдо рдЕрдВрддрд░ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕ рдЕрдзрд┐рд╡реЗрд╢рди рдХреА рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд
рд╡рд┐рдзреЗрдп рд▓рд┐рдВрдХ рдХреЛ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣
рджреВрдВрдЧрд╛ ред
Git, рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдкреНрд░рдпреБрдХреНрдд рд╕реНрд░реЛрдд рдХреЛрдбрдореВрд▓