---
title: Faster Tests With Capybara and Request Specs
teaser: System specs are cool, but can be slow and flaky. Request specs can be good
  enough if you add the right seasoning to them.
tags: rails,testing,capybara
author: Matheus Richard
published_on: 2024-04-15
---

Here's a cool trick to improve the performance of your test suite: **write more request specs and fewer system specs** (yes, you can use them for more than API testing).

Rails is very good at CRUD-y stuff, so if you don't have fancy interactions, request specs are often good enough (and less flaky). But I hear you, Capybara selectors (especially with [capybara\_accessible\_selectors](https://github.com/citizensadvice/capybara_accessible_selectors)) are so nice to use. So let's use them in request specs!

It's quite easy to get started. Add this to your RSpec configuration (somewhere in `spec/support/capybara.rb`):

```ruby
module CapybaraPage
  def page
    Capybara.string(response.body)
  end
end

RSpec.configure do |config|
  config.include CapybaraPage, type: :request
end
```

<q>What about <code>within</code>?</q>, you might ask. Well, that depends on a `Capybara::Session` object, but we can get something similar by writing expectations with a block:

```ruby
get users_path

expect(page).to have_table "Users" do |table|
  expect(table).to have_content user.name
  expect(table).to have_content user.email
end
```

And *voilà*! You now have requests specs that run fast\* *and* have powerful expectations to assert the page content!

<aside class="info">
  <p>
    * Using <a href="https://gist.github.com/MatheusRich/5f6dadd0fe70ea287a30158c2b67d3be">a very simple benchmark</a>,
    request specs are at least one order of magnitude faster than system specs with Selenium or Cuprite.
  </p>
</aside>

If that idea excites you, we've created a gem that implements that automatically for you: [action_dispatch-testing-integration-capybara](https://github.com/thoughtbot/action_dispatch-testing-integration-capybara).
