In many projects I 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, 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 ArticlesControllerand 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 publishedarticles by default and if we send the draft parameter will return the draft articles:
# frozen_string_literal: true
require "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.