Rubocop-rspec configuration

Pasha Kalashnikov
2 min readJul 15, 2024

We added rubocop-rspec to our Tramway gem. This is the first time I have used these special linter rules for RSpec.

Here is my `rubocop-rspec` configuration file with explanations of every rule.

# Single exception tests sounds good, but in practise it becomes a huge problem. Test examples run too many times and the whole test process becomes slow.
# Moreover, remember about `and` function that we can use. `expect(page).to have_css(css_1).and have_css(css_2)`
RSpec/MultipleExpectations:
Max: 3

# Let's see at this file https://github.com/Purple-Magic/tramway/blob/main/spec/helpers/navbar_helper_spec.rb
# 3 nested groups is not enough, cause we have levels `className` -> `functionName` -> `successOrFailure` -> `certain_case`. It should be 4 at least
RSpec/NestedGroups:
Max: 4

# According to expectations count. Let's imagine that we need 3 expectations in one test and also we need one line to make `service.call` or stuff like that. 3 * 3 + 1 = 10
RSpec/ExampleLength:
Max: 10


# I love this kind of expression `expect(form_class).to receive(:new).with(object).and_return(form_object)`, because it's short
RSpec/StubbedMock:
Enabled: false

Single / Multiple exceptions tests

RSpec/MultipleExpectations:
Max: 3

Single exception tests sound good, but it becomes a huge problem in practice. Test examples run too many times and the whole test process becomes slow.

Of course, we have andmethod that allows us to do this:

expect(page).to have_css(css_1).and have_css(css_2)

And I love this method and use it. But in time we have issues with test running duration the idea of merging single-expectation tests into multiple expectations tests comes first or second.

So, it’s a good idea to limit test expectations by 3.

Nested groups

RSpec/NestedGroups:
Max: 4

Let’s see at Tramway Navbar spec file.

# frozen_string_literal: true

require 'support/view_helpers'

describe Tramway::Helpers::NavbarHelper, type: :view do
before do
described_class.include ViewHelpers
view.extend described_class
end

let(:title) { Faker::Company.name }

describe '#tramway_navbar' do
context 'with success' do
let(:left_items_css) { 'nav .flex ul.flex.items-center.space-x-4' }
let(:right_items_css) { 'nav ul.flex.items-center.space-x-4' }

context 'with title checks' do
it 'renders navbar with title and default link' do
fragment = view.tramway_navbar(title:)

expect(fragment).to have_content title
expect(fragment).to have_css "a[href='/']"
end
end
end
end
end

We have groups that should be in one file:

Tramway::Helpers::NavbarHelper -> #tramway_navbar -> with success -> with title checks
  • Tramway::Helpers::NavbarHelper is a class name.
  • #tramway_navbar — method name
  • with success — group of cases
  • with title checks — attribute-specific cases

Let’s talk about these rules or another in the comments :)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response