Integration Testing with Selenium and Capybara

About Amy Wibowo

Life before frontend integration testing meant clicking links and buttons and testing everything by hand before launching any feature change.  But as every programmer knows, insanity is doing the same thing over and over again, and not writing code to do it for you.

Though it might seem daunting to set up a frontend integration testing environment, automating these tests is worth the effort.  

  • Javascript unit tests are great for testing programmatic interfaces to libraries, but they are ill-suited for testing behaviors dependent on the browser.
  • Testing by hand is unreliable and time-consuming.
  • Integration testing allows you to be more aggressive in refactoring frontend flows, since changes that break critical behaviors will be caught by the test.

For our frontend testing needs, we use a combination of Capybara and Selenium — Selenium because it’s a mature solution for automating browser interactions; Capybara because of its rspec-like syntax for specifying browser interactions.

Setup

Using Selenium requires installation of the selenium-webdriver gem, and Capybara requires installation of the capybara gem and the launchy gem for screengrabs. In your Gemfile:

Starting out
You can generate the test (with a template) with
rails g integration_test test_name
The auto-generated test will live in spec/requests look something like

Writing Tests

 

Within the test, you can use Capybara to describe any user interactions on a page.

 

- You can access pages:

 

visit some_path
click_link “Log In”

 

- You can interact with forms:

 

fill_in “email”, :with => “amy.wibowo@airbnb.com
fill_in “password”, :with => “secret”
choose(‘radio_button_name’)
check(‘checkbox_name’)
attach_file(‘Image’, ‘/path/to/image.jpg’)

 

The selectors can be id, label, or text– they’re lenient.  

 

click_button(“submit”)

 

- You can verify that the right thing happened

 

page.should have_content(“Hi, Amy!”)

 

- And you can test the Javascript on your page just by setting js to true

 

it “lets the user login via modal and email”, :js => true do

 

sample test:Running Tests

 

Afterwards, you can run the tests with rake spec:requests.  They also run as a part of bundle exec rake spec

 

A Few Tips

 

- Start off by writing tests for your main flow, for the greatest ROI.
- To keep the tests from being too fragile, use text selectors that are as general as possible (i.e. If your button says “Sign up now!” just check for “Sign up” in case the text changes in the future)

 

Further Reading

 

http://railscasts.com/episodes/257-request-specs-and-capybara
http://rubydoc.info/github/jnicklas/capybara/master/file/README.md

 

Stay tuned for a followup post on how we integrated Capybara tests with Jenkins, our continuous integration server!

1 comments

About Amy Wibowo

Speak Your Mind

*

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Comments

  1. manusingh

    How do you setup your environment? Do the test run against an existing live environment or setup the environment in hermetic way?