Since the release of RSpec 3.7 we’ve been able to take advantage of system tests which are new as of Rails 5.1. If you’ve been using RSpec for a while you’re already likely familiar with feature tests using Capybara. For those new to these types of tests: they allow us to test the actual actions of a user. Clicking, filling out forms, etc.
Going forward it sounds like the RSpec crew has blessed the system moniker and is encouraging its usage going forward. That being said, there are some differences in choosing to use system over feature you should be aware of.
Configuration
Setting up RSpec system tests is going to make it easier when it comes to configuring the Capybara browser.
You’ll need to configure a few things in /spec/rails_helper.rb
. I’m currently running a Rails 5.2.rc1 app, so your configs could be slightly different depending on which release you’re running.
Gemfile
Let’s make sure we’ve got the right gems in place to make all this work.
group :test do
gem 'capybara', '~> 2.15'
gem 'selenium-webdriver'
gem 'chromedriver-helper'
end
Don’t forget to bundle install
.
Register the drivers
Headless Chrome is a fairly new (and pretty great) way to do automated browser testing. Headless means we don’t have to sit there and watch a browser window get spawned and do a bunch of clicks and whatnot. It’s faster to let it do all that stuff behind the scenes.
# /spec/rails_helper.rb
RSpec.configure do |config|
...
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.register_driver :headless_chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: { args: %w(headless disable-gpu window-size=1024,768) }
)
Capybara::Selenium::Driver.new app,
browser: :chrome,
desired_capabilities: capabilities
end
end
Now, even though headless testing is faster than watching it live it’s still slower than we’d like. So let’s turn if off completely if we don’t need to test javascript.
# /spec/rails_helper.rb
RSpec.configure do |config|
...
# Ensures all non-javascript tests will use the faster :rack_test
config.before(:each, type: :system) do
driven_by :rack_test
end
# Ensures that all javascript tests use :headless_chrome
config.before(:each, type: :system, js: true) do
# Can be switched to :chrome if you want to see it working
driven_by :headless_chrome
end
end
Here’s an example of a test that’s going to use javascript and therefore trigger the use of headless Chrome. In this case we’re not testing anything javascripty, but notice the use of js: true
.
scenario 'visits home page', js: true do
visit root_path
expect(page).to have_content('Hello World!')
end
An example test
# /spec/system/home_spec.rb
require 'rails_helper'
RSpec.describe 'Home', type: :system do
scenario 'visits home page' do
visit root_path
expect(page).to have_content 'Hello World!'
end
end
This is a goofy test that doesn’t exert the capabilities of Capybara. Head over here to get a start on all it can do.
Final notes
- RSpec doesn’t seem to have a generator yet for system tests. In other words you’re not going to be able to do
rails g rspec:system foobar