Setup Rspec & Capybara
Add these gems to your Gemfile in the development, test group. This group applies to both the development and test environments.
gem :development, :test do
gem 'rspec-rails'
gem 'factory_bot_rails'
gem 'simplecov'
gem 'simplecov-rcov'
// other gems in the dev+test group
end
then run bundle install
(You’ll notice by default your Gemfile already has: gem 'capybara'
which we will be using. The //
comment lines above signify the other content inside of your :development, :test
group already. Be sure to check the gems already in your these groups for duplicates. If you have gems with version numbers, you can safely remove the version numbers for the purpose of this demo.)
then run rails generate rspec:install
Notice that this has created:
a hidden file .rspec
a folder spec/
spec/spec_helper.rb
spec/rails_helper.rb
COMMIT YOUR CHANGES HERE BEFORE CONTINUING.
1/ Configure SimpleCov for Coverage Reports
Open spec/rails_helper.rb
and add the code shown in orange below. (just below the line require 'rspec/rails'
). Also, be sure to add the configuration for FactoryBot in the Rspec config (also shown in orange.) Note here I like to remove the default comments that come with the generated file (I personally find them distracting), and I have done so here.
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
if( ENV['COVERAGE'] == 'on' )
require 'simplecov'
require 'simplecov-rcov'
class SimpleCov::Formatter::MergedFormatter
def format(result)
SimpleCov::Formatter::HTMLFormatter.new.format(result)
SimpleCov::Formatter::RcovFormatter.new.format(result)
end
end
SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
SimpleCov.start 'rails' do
add_filter "/vendor/"
add_filter "/test/"
end
end
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
end
Capybara.default_driver = :rack_test
Now create a spec/features/ using
mkdir spec/features
Finally, I recommend you add the coverage/
folder — which is where you code coverage reports will be automatically output to — into your .gitignore
file. Just open .gitignore
and add a line that reads:
coverage/
Alternatively, you can decide to check-in your coverage reports with each commit.
What this code above will do is it will generate coverage reports whenever you run RSpec using COVERAGE=on
, like so:
COVERAGE=on ./bin/rake rspec
You simply prepend (put before) the text COVERAGE=on
to the rspec command as you run it.
Alternatively, modify the Ruby code above to remove the line if( ENV['COVERAGE'] == 'on' )
(and its end statement) and your coverage reports will run every time you run rspec.
COMMIT YOUR CHANGES HERE BEFORE CONTINUING.
2/ Set up a Route and A Blank Welcome Page
Now let’s take a quick detour and set up a basic Rails route and view. Go to config/routes.rb and add
Rails.application.routes.draw do
root to: "welcome#index"
end
Create an empty controller welcome_controller.rb:
rails generate controller Welcome
Create a folder views/welcome/index.erb
In this file put
Hello World
COMMIT YOUR CHANGES HERE BEFORE CONTINUING.
3/ Setup Capybara
To turn Capybara on, go to rails_helper.rb, again and again, and modify the RSpec.configure
block. Add the config.include Capybara::DSL
to the RSpec.configure
block.
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
config.include FactoryBot::Syntax::Methods
config.include Capybara::DSL
end
Notice that there is an important setting here that is already enabled by default: config.infer_spec_type_from_file_location!
This tells Rspec that the specs in the system/
folder automatically feature specs, the specs in the requests/
folder are automatically request specs, etc.
Now go back to spec/features/
In this folder, create a file called math_spec.rb
. When you make a feature spec, you must ‘tell’ Rspec it is a feature spec in one of two ways:
1) If the setting config.infer_spec_type_from_file_location! is on (as seen above), a spec in the features folder will automatically be considered a feature spec, or
2) you specify it is a feature spec using type: :feature
(as shown below).
require 'rails_helper'
describe "take a quiz", type: :feature do
it "asks me to add to two numbers" do
visit '/'
expect(page).to have_content 'What is 5+2'
end
end
If we run rspec
or ./bin/rake spec
, we see that we can’t find the text ‘What is 5+2’ inside of ‘Hello world’
Excellent! A failing spec. Just for shoots & gurgles, let’s change the spec like so:
Add the line shown in orange and remove the line with the strikethrough text.
require 'rails_helper'
describe "take a quiz", type: :feature do
it "asks me to add to two numbers" do
visit '/'
expect(page).to have_content 'What is 5+2'
expect(page).to have_content 'Hello World'
end
end
Run bin/rake spec
again and we get a passing spec as expected.
COMMIT YOUR CHANGES HERE BEFORE CONTINUING.
4/ Switch from Rack-Test To a Javascript Driver
TODO: (write something here)
5/ Understanding Transactional Fixtures
TODO: (write something here)
6/ Setting Up FactoryBot
Go back to rails_helper.rb
and add this:
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
config.include FactoryBot::Syntax::Methods
end
TODO: (write something here)