Integration Testing with Selenium and Capybara
By 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.
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!
Check out all of our open source projects over at airbnb.io and follow us on Twitter: @AirbnbEng + @AirbnbData
Originally published at nerds.airbnb.com on March 22, 2012.