How do I organize my RSpec files
In many projects I’ve worked, I always have the same issue, big and giant RSpec files that ends up with a stress and mess that can’t event let you read the file comfortable, having too many lines in one file is really a nightmare.
So I decided to organize my specs in multiple files organizing them in folders and files per action, context & describe blocks, validations etc…
By this way I have a separated file per case, obviously we will have repeated code and for this we should create a shared context to handle the code in one place and follow the DRY pattern.
Example: lets say we have ArticlesController
and we want to test the API CRUD actions index, create, show, update, destroy
, so we have five actions to be tested in one file, after doing all those specs, your file will become a giant file and will be hard to navigate between the actions to reach the code, so I prefer to divide this file and create a file per action:
- specs/requests/articles/index_spec.rb
- specs/requests/articles/create_spec.rb
- specs/requests/articles/show_spec.rb
- specs/requests/articles/update_spec.rb
- specs/requests/articles/destroy_spec.rb
Another example, lets say that the article can be draft and published, so if we have 5 published articles and 2 draft articles we need to be sure that the index
action returns the published
articles by default and if we send the draft
parameter will return the draft articles:
# frozen_string_literal: truerequire "rails_helper"RSpec.describe("Articles", type: :request) do
before do
create_list(:article, 2, status: :draft)
create_list(:article, 5, status: :published)
end describe "GET /api/articles" do
context "without draft param" do
befor do
get("/api/articles")
end it 'returns only published articles' do
expect(json_response.count).to(eq(5))
end
end context "with draft param" do
befor do
get("/api/articles", params: { draft: true })
end it 'returns only draft articles' do
expect(json_response.count).to(eq(2))
end
end
end
end
Imagine if you have more specs per context, your file will become a giant spec file, for me I feel more comfortable read small files rather than big files, so I prefer to divide the file into two files, one per context grouping them in one folder name as the action:
- specs/requests/articles/index/published_spec.rb
- specs/requests/articles/index/draft_spec.rb
Same thing can be done for Models and Service Objects, this helps me to keep files organized in correct folders as namespaces.
Thanks for reading.