I’d like to share how to add testing to your already built rails application in this blog, and I will do it with the examples of my application.
I will cover the basics and show how to get started and then we will be writing tests for routes, models, and controllers in a little bit.
First things first, Setup:
In your gem file, we need to add rspec-rails gem:
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
The next step is to run bundle and install RSpec that will generate a few files for us:
# Download and install
$ bundle install# Generate boilerplate configuration files
# (check the comments in each generated file for more information)
$ rails generate rspec:install
Now let’s set up a test database for our tests to be able to run, so here is a thing, I’ve been using a Postgres database for development and production, however, I don’t want to set up another Postgres DB for my test environment so I’ll just use sqlite3 for that purpose and will show you how to change the config of the application to accommodate just that.
First, let’s regroup database gems in Gemfile:
group :development, :production do
gem 'pg', '~> 1.1'
endgroup :test do
Second, after running bundle install we’ll open a config/database.yml and will change our test config to this:
Third, we’ll go to config/environments/test.rb file and add a line of code:
config.active_record.maintain_test_schema = true
So this is basically all of the DB set up, last thing we’ll do is to run the DB migration for our test env so DB is ready to go:
rails db:create RAILS_ENV=test
rails db:migrate RAILS_ENV=test
Awesome, we are done here, let’s write some tests!
let create a new folder and a file for that spec:
require "rails_helper"RSpec.describe "Routes", :type => :routing do# tests will go hereend
Here is our initial setup, We’re requiring rails_helper and declaring a type of specs to be :routing, meaning that tests written here are meant to test our routes.
I’ll advise you to write a bunch of descriptions first before you’ll get into details, basically describe if first, and then fill them all up like that:
require "rails_helper"RSpec.describe "Routes", :type => :routing doit "route '/' to point root page, application#welcome"it "route /google_auth to point to the sessions#google_auth"it "route /logged_in to point to the sessions#is_logged_in?"it "route /logout to point to the sessions#destroy"end
to test routing you want to make sure that route points to the right controller and is available for reach, which you can test it like that:
it "route '/' to point root page, application#welcome" doexpect(get("/")).to route_to("application#welcome")expect(get("/")).to be_routableend
and follow with this pattern for the rest of the routes
to test route with an argument we pass through the URL would look like this:
it "route /get_menu/:id to point to the users#get_menu" doexpect(get("get_menu/1")).to route_to(controller: "users", action: 'get_menu', id: '1')expect(get("/get_menu/1")).to be_routableend
let’s generate users specs with our generator in the console:
rails generate rspec:model user
that’ll generate a spec file for us with a type of model for the User, and have a look at few examples of testing I wrote for my application:
where I mostly test my Model’s validation
and another model testing with active storage associations:
I’ll show you my testing for the session controllers, once again my Rails application and a backend so all of the responses it renders in JSON, and it’s being tested accordingly:
In User Controller, I’ve used before_each hook to pre declare variables to use in most of my actions. Also, I’ve used
file = fixture_file_upload('test.pdf', 'application/pdf')
to test file uploads and active record associations, just add a file to this path:
where test.pdf is a name and a type of the file.
So this is pretty much it, and definitely, a good start, if you need to find out more please read on from the official RSpec website, and thanks for reading.