We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
August 13, 2024
3 tips to up your RSpec game
EMIR VATRIC
👋 Hi there!
Tests, annoying but necessary!
Inday-to-day work every developer should be asked to write tests for their work, and if one is not asked he should ask for them. While they are cumbersome and annoying to write, and usually are an afterthought, they come really useful down the line when refactoring the code, upgrading the framework, or using them as a form of documentation for the feature.
Here are a few tips that helped me to write cleaner, more structured, and overall better specs. Implementing these tips will also streamline your workflow and give you direction and a better idea on how to go on about testing in general.
Structure the code
Ifwe embrace the premise that tests are going to serve as documentation for our code, that it is important to write descriptive tests, and use what framework provides us with describe, context, it.
Here is an example from an open-source project called ChatWoot, which I can’t recommend enough for you to check.
require 'rails_helper'
RSpec.describe 'Profile API', type: :request do
describe 'PUT /api/v1/profile' do
context 'when it is an unauthenticated user' do
it 'does something' do
...
end
end
context 'when it is an authenticated user' do
it 'does something' do
...
end
end
end
describe 'GET /api/v1/profile' do
context 'when it is an unauthenticated user' do
end
context 'when it is an authenticated user' do
end
end
end
In this example, it is easy to understand what we are testing, and how it is supposed to behave given the context. So now when somebody else is trying to do the work, instead of reading the code, he can read the specs and understand what is the purpose of given endpoints.
Use Data Factories
Data Factory (or factory in short) is a blueprint that allows us to create an object, or a collection of objects, with predefined sets of values. While you can do your work without them, you definitely should use them. Factories will make your code DRY and your workflow faster and easier.
I personally use FactoryBot, it is easy to set up and there is almost no learning curve, everything you need is well documented and easy to implement.
Let’s take a look at a quick example, considering this model:
class Article < ApplicationRecord
belongs_to :author, class_name: "User"
enum status: %i[unpublished published]
end
We can produce a factory that can create all the necessary data for one objec
FactoryBot.define do
factory :article do
sequence :name, 'Article 000'
association :author, factory: :user
trait :published do
status :published
end
trait :unpublished do
status :unpublished
end
end
end
From reading this gist we can conclude that next time we want to create an article object, that is published with user auto-created we can just call:
create :article, :published
From this single line, we will create a new Article, and User object with name and status attributes, obviously these can be overridden if we pass different values for them, this is obviously a lot better than creating multiple objects manually.
But this is not all that FactoryBot has to offer, it has all kinds of useful callbacks built for different scenarios that you might run into. All of these features are made to make your life easier, and your code cleaner, it is definitely worth looking into, Getting Started.
Track your Cove Coverage
The best way to know if you have tested your code well is to track your coverage with one of the tools designed to do just that. Note that checking if your code is covered is not as same as checking if your tests are effective.
Having your codebase covered with tests is very useful, and it is a sign of a healthy project and responsible developers.
To check my code coverage I use SimpleCov, it is simple to set up and gives you great data to check your coverage line by line.
Setup is easy, add simplecov to your gemfile, and in top of your
or spec_helper.rb
add:rails_helper
require 'simplecov'
SimpleCov.start :rails
And setup is done after your specs are done running you will get generate an HTML file that is super easy to understand and read.
Conclusion
Love them or hate them, testing your code is an integral part of every developer's day, as soon as you embrace writing test, and start considering them as a big part of the development process, rather them an afterthought life is going to become easier.
These tools helped me to up my Rspec game, and I had to learn it the hard way, all the way from the beginning when I wasn't paying the attention to my coverage till now when I have to go back and cover the missed lines.