---
title: End-to-End Testing with RSpec Integration Tests and Capybara
teaser:
tags: web,testing,ruby,rails
author: Harlow Ward
published_on: 2012-10-26
---

![Integration tests with rspec and capybara][tests]

[tests]: http://imageshack.us/a/img89/9121/integrationtestingmakesg.jpg

Stability can become an issue as web applications evolve and grow -- integration
tests provide a great way to perform end-to-end tests that validate the
application is performing as expected.

## Integration test with RSpec and Capybara

When writing integration tests, try to model the test around an actor (user of
the system) and the action they are performing.

```ruby
# spec/features/visitor_signs_up_spec.rb
require 'spec_helper'

feature 'Visitor signs up' do
  scenario 'with valid email and password' do
    sign_up_with 'valid@example.com', 'password'

    expect(page).to have_content('Sign out')
  end

  scenario 'with invalid email' do
    sign_up_with 'invalid_email', 'password'

    expect(page).to have_content('Sign in')
  end

  scenario 'with blank password' do
    sign_up_with 'valid@example.com', ''

    expect(page).to have_content('Sign in')
  end

  def sign_up_with(email, password)
    visit sign_up_path
    fill_in 'Email', with: email
    fill_in 'Password', with: password
    click_button 'Sign up'
  end
end
```

## Extracting common test functionality

To share code between features move common capybara steps into a Ruby module in
the rspec support directory.

```ruby
# spec/support/features/session_helpers.rb
module Features
  module SessionHelpers
    def sign_up_with(email, password)
      visit sign_up_path
      fill_in 'Email', with: email
      fill_in 'Password', with: password
      click_button 'Sign up'
    end

    def sign_in
      user = create(:user)
      visit sign_in_path
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
      click_button 'Sign in'
    end
  end
end
```

Modules must be explicitly included to share the common code between integration
tests.

```ruby
# spec/support/features.rb
RSpec.configure do |config|
  config.include Features::SessionHelpers, type: :feature
end
```

## Running the integration tests

```bash
$ rspec -fd
Visitor signs up
  with valid email and password
  with invalid email
  with blank password

Finished in 0.35837 seconds
3 examples, 0 failures
```

## Takeaways

- Maintain application stability with end-to-end test coverage
- Use RSpec to run your integration tests
- Modules allow shared Capybara steps between specs

## What's next

If you found this useful, you might also enjoy:

- [Describe the User's Perspective: DDD, acceptance testing, and you][ddd]
- [The Quest Continues: Introducing capybara-webkit][quest]

[ddd]: https://thoughtbot.com/blog/describe-the-users-perspective-ddd-acceptance
[quest]: https://thoughtbot.com/blog/capybara-webkit
