This tutorial will help guide you through the process of setting up a new Ruby on Rails project with robust testing capabilities. This tutorial makes a couple of assumptions:
- You have installed Ruby on Rails and have a rudimentary understanding of how to use it.
- You have installed bundler
- Essential:
- rspec-rails
- factory_girl_rails
- database_cleaner
- capybara
- launchy
- byebug (included by default)
- Nice to have but not absolutely necessary:
A highly popular testing framework and DSL written in Ruby, for testing Ruby on Rails projects. It was written with the goal of facilitating Behaviour Driven Development
A fixtures replacement tool that easily allows one to generate ruby objects to be used in testing. It has a rich set of features that allows you handle just about any scenario you may encounter in your testing suite.
A gem for cleaning database entries in the testing environment. This ensures that every test is being run with a clean slate. FactoryGirl and DatabaseCleaner work in tandem where FactoryGirl builds ruby objects and saves them to the database to be used in a test and DatabaseCleaner cleans the database of that entry after the test is completed.
Allows you to interact with web applications through your tests in the same way that a real user would.
When installed with capybara, gives you access to the save_and_open_page
method which when used in a feature tests saves a snapshot of the page being tested in it's current state and opens the page in a browser window. Usefull for debugging. Beware that launchy will save and open the page without styling.
Set's breakpoints in your code and enters you into a debugger shell inside your terminal window and allows you to interact with the environment in it's current state. Operates similarly to 'Pry'.
Allows Capybara to interact with and test Javascript.
Makes writing model tests really easy. I wouldn't install this gem until you have gotten used to using rspec without it. Gives you a large library of one-line rspec expectations that test common rails functionality. Can save a great deal of time when writing tests and shortens code length. It will probably be beneficial to understand how to test these expectations manually before using Shoulda-Matchers.
Provides RSpec expectations for Callback methods. Everything I said about Shoulda-Matchers also applies to Shoulda-Callback-Matchers
Allows you to access and interact with session data in testing.
In the directory that you would like the project to exist run in your console:
rails new app_name -d postgresql -T
If we break this command down:
rails new
generates a new rails project
app_name
is the name of the project you are creating.
-d postgresql
specifies postgresql as the the database used in the app.
-T
Removes the default testing framework, MiniTest.
Then cd
into your new project directory and code .
Add the gems to their respective environments:
group :test do
gem 'capybara'
gem 'database_cleaner'
gem 'faker'
gem 'launchy'
gem 'selenium-webdriver'
gem 'shoulda-callback-matchers', '~> 1.1.1'
gem 'shoulda-matchers', '~> 3.1'
end
group :development, :test do
gem 'byebug', platform: :mri
gem 'factory_girl_rails'
gem 'rack_session_access'
gem 'rspec-rails'
end
group :development do
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'web-console', '>= 3.3.0'
end
Bonus points if they are sorted alphabetically.
After adding all of your gems, run bundle
in your terminal to install them.
Now that all your gems are installed you can install rspec in your rails app. In your terminal:
rails generate rspec:install
This will create a spec
directory in your rails project that contains two files: rails_helper.rb
and spec_helper.rb
. It will also create a .rspec
file in your project's parent directory.
If you would like to change the format of RSpec's output you can do so in your .rspec
file by adding the line: --format documentation
For pretty colors: RSpec-Pride
In spec/rails_helper.rb
add require 'capybara/rails'
By default, capybara uses the :rack_test driver to simulate a browser environment. It is fast but does not support JavaScript. If you have the gem selenium-webdriver
installed you can run tests with the Selenium server by writing js: true
in your tests that require javascript. Example:
describe 'some stuff which requires js', js: true do
it 'will use the default js driver'
it 'will switch to one specific driver', :driver => :webkit
end
Review this tutorial for more information on testing with Selenium.
More on using capybara with javascript coming soon!
In rails_helper.rb
find the line config.use_transactional_fixtures = true
and
change true
to false
. If you are curious what this does, look here
In your console: mkdir spec/support
And then: touch spec/support/database_cleaner.rb
This is where you will put your DatabaseCleaner configuration for RSpec.
Open that file and add the code :
RSpec.configure do |config|
config.before(:suite) do
begin
DatabaseCleaner.start
FactoryGirl.lint
ensure
DatabaseCleaner.clean_with(:truncation)
end
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
If you would like an explanation of what each line of code in this file does, look here and here
Finally, look in rails_helper.rb
, find the line:
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
and uncomment it. This will allow rails to find all the the files in your newly created spec/support
directory.
touch spec/support/factory_girl.rb
Open that file and write:
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
This will make FactoryGirl's methods available in all of your tests.
You have two choices for where you can build your factories. If you are working on a relatively small project that will only have a few factories you can touch spec/support/factories.rb
create all your factories in that file. Alternatively, if you are working on a larger project that will likely have a lot of factories, you can mkdir spec/support/factories
and then make individual factory files within that directory.
Open rails_helper.rb
and place this code at the bottom of the file.
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
This code tells Shoulda-Matchers that you plan to use RSpec and want to make available all of ShouldaMatcher's methods.
Shoulda-Callback-Matchers should work without any configuration if you have Shoulda-Matchers installed. However, if you run into an undefined method 'callback'
error try including this code at the bottom of your rails_helper.rb
file:
RSpec.configure do |config|
config.include(Shoulda::Callback::Matchers::ActiveModel)
end
In config/environments/test.rb
add the line:
[MyRailsApp]::Application.configure do |config|
...
# Access to rack session
config.middleware.use RackSessionAccess::Middleware
...
end
Add to spec/spec_helper.rb
the line: require 'rack_session_access/capybara
Open up spec/support/database_cleaner.rb
and add this code at the bottom of your Rspec.configure block:
config.around(:each) do |example|
example.run
Capybara.reset_sessions!
end
This will reset the session data created by Rack_Sesson_Access after each example in your test run. Read more about around hooks here
One last step before your project is ready to go. In your console:
rake db:create