Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Pattern for Functional Testing

Pivotal Labs
Friday, November 14, 2008

Regular Selenium tests (in Java) might look like:

selenium.open("/login");
selenium.type("id=username", "bob");
selenium.type("id=password", "password");
selenium.click("Login");
selenium.waitForPageToLoad();
selenium.click("My Account");
selenium.waitForPageToLoad();
assertEquals("bob", selenium.getText("//table[2]/tr[3]/td[2]/");

After a few tests, this kind of thing becomes painful to manage. The typical solution is to create a bunch of constants for IDs and Xpaths, but that doesn’t help too much.

Fellow Pivot Mike Grafton came up with a cool pattern for improving on this. The idea is to create a class representing each page of your web app. Each class contains two types of methods: a bunch of action methods (clickMyAccountLink(), typeUsername()), and a bunch of inspection commands (isLoginButtonEnabled(), getLoggedInUsername()).

When an action takes you to a new page, the corresponding action method returns a new class representing that page. When it stays on the same page, the method just returns “this”. This allows methods to be chained to make the tests more readable.

Here’s how that test would look using this new pattern:

MyAccountPage myAccountPage = new LoginPage(selenium)
  .typeUsername("bob")
  .typePassword("password")
  .clickLoginButton()
  .clickMyAccountLink();

assertEquals("bob", myAccountPage.getLoggedInUsername());

The constructor of each page class should validate that it’s on the correct page (waiting if necessary, and perhaps asserting on the page title).

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

9 Comments

  1. Luke Melia says:

    Ouch. This is crying for webrat.

    November 14, 2008 at 8:59 pm

  2. Russ says:

    It needs a cool name! Like “Functional Mirror Pattern”

    November 14, 2008 at 9:29 pm

  3. Parker Thompson says:

    @luke: the syntax may be nice, but webrat doesn’t solve the same problem as selenium. We tend to rely on selenium because we want to prove that it works given (or in spite of) the browser’s interpretation of the html/js. Often this really matters, especially if your site has any dom-modding js.

    November 14, 2008 at 10:03 pm

  4. Wes Maldonado says:

    @Russ I’ve always heard this called the Logical Functional Model:

    * http://blogs.msdn.com/micahel/archive/2005/07/27/TheLfmApplied.aspx
    * http://blogs.msdn.com/micahel/archive/2005/06/22/UseYourUsersViewpoint.aspx

    November 14, 2008 at 10:59 pm

  5. Dave Smith says:

    @Wes Sadly, “Logical Functional Model” has a ring to it like a lead bell.

    November 15, 2008 at 2:29 am

  6. Dave Smith says:

    See also: http://code.google.com/p/webdriver/wiki/PageObjects

    November 15, 2008 at 4:55 am

  7. Josh Knowles says:

    As Luke mentioned this is a perfect use case of Webrat. In fact as of a month or so back you can leverage Webrat to drive Selenium.

    At weplay we have Cucumber features which drive our integration tests via Webrat & Selenium and it works great.

    Reference: http://github.com/brynary/webrat/tree/master/lib/webrat/selenium/selenium_session.rb

    November 15, 2008 at 7:31 am

  8. Erik Hanson says:

    Josh & Luke: This pattern could definitely be applied to webrat or any other similar tool. My example was in Java and Selenium because that’s where I’ve used this pattern the most. Recently in fact we used this pattern to control an Adobe AIR app.

    November 15, 2008 at 4:43 pm

  9. kasino888 says:

    Functional debugging of application specific integrated circuits (ASICs) has been recognized as a very labor-intensive and expensive process. It often dominates the time and cost of the ASIC system development.Functional specification of the design is logically partitioned into linear and nonlinear components. This is is one of those practices that has not caught on as much as other technical practices in the Agile community.Thanks for the update!!

    March 20, 2009 at 5:44 am

Add New Comment Cancel reply

Your email address will not be published.

Pivotal Labs

Pivotal Labs

Recent Posts

  • Does the set of all sets contain itself?
  • Standup 3/8/2012
  • Standup 3/7/2012
Subscribe to Pivotal's Feed

Author Topics

riddles (1)
agile (167)
capistrano (2)
rails (26)
movember (1)
git (10)
railsdoc (1)
object-design (1)
bdd (3)
cucumber (3)
linkedin (1)
oauth (1)
ruby (17)
tdd (2)
lvh.me (1)
rails 3.1.1 (1)
selenium (6)
homebrew (1)
mysql (5)
rvm (1)
sproutcore (1)
paperclip (2)
pry (1)
amazon (1)
heroku (1)
rails3 (2)
jasmine (3)
design (3)
process (12)
productivity (8)
learning (1)
olin (1)
migrations (2)
mongodb (2)
devise (2)
javascript (13)
rubymine (4)
ipad (1)
whurl (1)
head.js (1)
pairing (2)
tools (4)
pair programming (1)
rspec (10)
rspec2 (1)
ruby19 (1)
incubation (3)
startup (5)
api (1)
presenter (1)
vanna (1)
pivotal tracker (5)
capybara (1)
fakeweb (1)
webmock (1)
intern (1)
ruby on rails (25)
meetup (1)
textmate (1)
testing (20)
solr (4)
nyc-standup (11)
community (1)
opensource (3)
activerecord (4)
chrome (1)
mp4 (1)
activeresource (1)
flash (3)
neo4j (1)
nginx (1)
rsoc (1)
meta programming (1)
agile standup (7)
government (3)
webos (4)
xss (1)
jquery (1)
bundler (2)
ci (3)
gems (5)
postgresql (1)
geminstaller (1)
gemcutter (1)
cloud (2)
rack (2)
refraction (1)
gem (5)
refactoring (1)
validations (1)
webrat (1)
engine-yard (1)
firefox (2)
jsunit (1)
mongrel (2)
thin (1)
unicorn (1)
facebook (1)
rubygems (5)
jruby (1)
actioncontroller (1)
rails 2.3 (1)
palmpre (1)
autotest (1)
mac (2)
hosting (1)
goruco (11)
database (3)
railsconf (11)
gogaruco (4)
deployment (4)
github (1)
ie (1)
ajax (1)
intellij (1)
json (1)
asset packaging (1)
polonium (1)
character encoding (1)
utf-8 (1)
test (3)
civics (1)
hpricot (1)
rake (3)
sms (1)
unicode (1)
iphone (1)
java (1)
safari (1)
memory leaks (1)
rr (3)
editor (1)
css (1)
nyc (3)
performance (5)
fun (5)
enterprise rails (1)
health (1)
new and cool (1)
general (2)
treetop (1)
errors (1)
stack (1)
trace (1)
cache (1)
cookies (1)
freesoftware (1)
conferences (1)
development (1)
driven (1)
proxy (1)
caching (1)
peertopatent (1)
languages (1)
rest (2)
rubyforge (1)
sake (1)
file (1)
upload (1)
constants (1)
osx (1)
terminal (1)
pairprogramming (2)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >