Skip to content

Instantly share code, notes, and snippets.

@yevgenko
Created June 1, 2018 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yevgenko/0712f6ff6352256161afdf6e9b1f9515 to your computer and use it in GitHub Desktop.
Save yevgenko/0712f6ff6352256161afdf6e9b1f9515 to your computer and use it in GitHub Desktop.
Designing End To End Test https://www.websequencediagrams.com/
title Designing End To End Test
Test->ApplicationRunner: perform_foobar_for(order)
ApplicationRunner->OrderPage: perform_action(Order::ACTION_FOOBAR)
OrderPage->CapybaraPage: visit('/orders/order.id')
OrderPage->CapybaraPage: click(text)
Test->ApplicationRunner: has_shown_foobar_status_for(order)
ApplicationRunner->OrderPage: shows_status(Order::STATUS_FOOBAR)
OrderPage->CapybaraPage: visit('/orders/order.id')
OrderPage->CapybaraPage: assert_text(text)
note left of Test
Review of Concerns (reasons for change):
* Test: when behaviour need be changed
* ApplicationRunner: when application internal
...details changes, such as constant or new pages added
* OrderPage: when order page UI need be changed
...or when capybara interface (DSL) changes
What if we remove OrderPage?
* application runner will need to know about UI
and when UI change, it will need be changed in turn,
thing will get more "interesting" with
more objects/pages
What if we remove ApplicationRunner?
* test will need to know about order page and
application details
Excersice:
Draw diagram for above cases,
i.e. remove one or two collaborators and
see how messages distributed between remainign objects
asses concerns (reason for change) for each object
compare results
end note
# Sample Implementation with RSpec
describe "Orders Management", type: :feature, js: true do
let(:application) { ApplicationRunner.new }
let(:order) { Fabricate :order }
it 'performs foobar on the order' do
application.perform_foobar_for(order)
expect(application).to have_shown_foobar_status_for order
end
# notice cohesion with page object "page_for"
class ApplicationRunner
def perform_foobar_for(order)
page_for(order).perform_action Order::FOOBAR_ACTION
end
def has_shown_foobar_status_for?(order)
page_for(order).shows_status Order::STATUS_FOOBAR
end
private
def page_for(order)
OrderPage.new(order)
end
# notice cohesion with capybara DSL "page"
class OrderPage
include Capybara::DSL
def initialize(order)
navigate_to order
end
def shows_status(text)
# usually more complicated, i.e. with selectors, etc.
page.assert_text text
end
def perform_action(name)
page.click name
end
private
def navigate_to(order)
page.visit "/orders/#{order.id}"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment