RuboCopにRSpecのルールが提供されているので導入してみました。
RSpecのルールはデフォルトだと厳し過ぎるのと、あえて従いたくないルールもあるので設定変更しました。今まで書いていたものも、自分なりのルールで書いているので、極力修正不要なように。
可読性は大事だけど、lint通す為に時間を掛け過ぎても、本来実現したいデリバリーを早くする事が難しくなるので。

RuboCop RSpec :: RuboCop Docs

参考: 既存のルール調整

先に既存のルールを調整したので、参考までに記載しておきます。

.rubocop.yml

inherit_from: .rubocop_todo.yml

AllCops:
  NewCops: enable
  SuggestExtensions: false
  Exclude:
    - 'bin/*'
    - 'db/schema.rb'
    - 'node_modules/**/*'

### Layout
# https://docs.rubocop.org/rubocop/cops_layout.html

# C: Layout/LineLength: Line is too long.
Layout/LineLength:
  Max: 160

### Metrics
# https://docs.rubocop.org/rubocop/cops_metrics.html

# C: Metrics/AbcSize: Assignment Branch Condition size for expect_space_json is too high.
Metrics/AbcSize:
  Exclude:
    - 'spec/**/*'

# C: Metrics/BlockLength: Block has too many lines.
Metrics/BlockLength:
  Exclude:
    - 'app/views/**/*.jbuilder'
    - 'config/environments/*'
    - 'config/routes.rb'
    - 'config/routes/*'
    - 'lib/tasks/**/*'
    - 'spec/**/*'

# C: Metrics/ClassLength: Class has too many lines.
Metrics/ClassLength:
  Enabled: false

# C: Metrics/MethodLength: Method has too many lines.
Metrics/MethodLength:
  Max: 30
  Exclude:
    - 'db/migrate/*'
    - 'spec/**/*'

# C: Metrics/ModuleLength: Module has too many lines.
Metrics/ModuleLength:
  Enabled: false

# C: Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
Metrics/ParameterLists:
  Exclude:
    - 'spec/**/*'

### Naming
# https://docs.rubocop.org/rubocop/cops_naming.html

# C: Naming/AccessorMethodName: Do not prefix writer method names with set_.
Naming/AccessorMethodName:
  Enabled: false

# C: Naming/VariableNumber: Use normalcase for method name numbers.
Naming/VariableNumber:
  Exclude:
    - 'spec/**/*'

### Style
# https://docs.rubocop.org/rubocop/cops_style.html

# C: Style/AsciiComments: Use only ascii symbols in comments.
Style/AsciiComments:
  Enabled: false

# C: [Correctable] Style/BlockComments: Do not use block comments.
Style/BlockComments:
  Enabled: false

# C: Style/ClassAndModuleChildren: Use nested module/class definitions instead of compact style.
Style/ClassAndModuleChildren:
  Enabled: false

# C: [Correctable] Style/ConditionalAssignment: Use the return of the conditional for variable assignment and comparison.
Style/ConditionalAssignment:
  Enabled: false

# C: Style/Documentation: Missing top-level class documentation comment.
Style/Documentation:
  Enabled: false

# C: [Correctable] Style/DoubleNegation: Avoid the use of double negation (!!).
Style/DoubleNegation:
  Enabled: false

# C: Style/FormatStringToken: Prefer annotated tokens (like %s) over unannotated tokens (like %s).
Style/FormatStringToken:
  Enabled: false

# C: Style/FrozenStringLiteralComment: Missing frozen string literal comment.
Style/FrozenStringLiteralComment:
  Enabled: false

# C: Style/GuardClause: Use a guard clause (*) instead of wrapping the code inside a conditional expression.
Style/GuardClause:
  Enabled: false

# C: [Corrected] Style/IfInsideElse: Convert if nested inside else to elsif.
Style/IfInsideElse:
  Enabled: false

# C: [Corrected] Style/Lambda: Use the -> { ... } lambda literal syntax for all lambdas.
Style/Lambda:
  EnforcedStyle: literal

# C: [Corrected] Style/NumericLiterals: Use underscores(_) as thousands separator and separate every 3 digits with them.
Style/NumericLiterals:
  MinDigits: 7

# C: [Correctable] Style/NumericPredicate: Use xxx.positive?/zero? instead of xxx > 0/== 0.
Style/NumericPredicate:
  Enabled: false

# C: Style/OptionalBooleanParameter: Use keyword arguments when defining method with boolean argument.
Style/OptionalBooleanParameter:
  Enabled: false

rubocop-rspecインストール

Installation :: RuboCop Docs

Gemfile

group :development, :test do
  # Use RuboCop
  gem 'rubocop'
  gem 'rubocop-rails'
+  gem 'rubocop-rspec'
% bundle install

.rubocop.yml

### RSpec
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html
require: rubocop-rspec
RSpec:
  Enabled: true

RSpecのルール変更

rubocopコマンドの実行とルールの追加 or 修正を通るまで、繰り返しました。

無効にしたルール

.rubocop.yml

# C: RSpec/ContextWording: Context description should match /^when\b/, /^with\b/, or /^without\b/.
RSpec/ContextWording:
  Enabled: false

# C: RSpec/DescribeSymbol: Avoid describing symbols.
RSpec/DescribeSymbol:
  Enabled: false

# C: [Correctable] RSpec/EmptyLineAfterExample: Add an empty line after it.
RSpec/EmptyLineAfterExample:
  Enabled: false

# C: [Correctable] RSpec/EmptyLineAfterExampleGroup: Add an empty line after shared_examples_for.
RSpec/EmptyLineAfterExampleGroup:
  Enabled: false

# C: [Correctable] RSpec/EmptyLineAfterFinalLet: Add an empty line after the last let.
RSpec/EmptyLineAfterFinalLet:
  Enabled: false

# C: [Correctable] RSpec/EmptyLineAfterHook: Add an empty line after before.
RSpec/EmptyLineAfterHook:
  Enabled: false

# C: [Corrected] RSpec/EmptyLineAfterSubject: Add an empty line after subject.
RSpec/EmptyLineAfterSubject:
  Enabled: false

# C: RSpec/ExampleLength: Example has too many lines.
RSpec/ExampleLength:
  Enabled: false

# C: RSpec/ExpectInLet: Do not use expect in let
RSpec/ExpectInLet:
  Enabled: false

# C: [Corrected] RSpec/ImplicitSubject: Don't use implicit subject.
RSpec/ImplicitSubject:
  Enabled: false

# C: RSpec/InstanceVariable: Avoid instance variables - use let, a method call, or a local variable (if possible).
RSpec/InstanceVariable:
  Enabled: false

# C: RSpec/MissingExampleGroupArgument: The first argument to context should not be empty.
RSpec/MissingExampleGroupArgument:
  Enabled: false

# C: RSpec/MultipleExpectations: Example has too many expectations
RSpec/MultipleExpectations:
  Enabled: false

# C: RSpec/MultipleMemoizedHelpers: Example group has too many memoized helpers
RSpec/MultipleMemoizedHelpers:
  Enabled: false

# C: RSpec/NestedGroups: Maximum example group nesting exceeded
RSpec/NestedGroups:
  Enabled: false

# C: RSpec/RepeatedExampleGroupBody: Repeated context block body on line(s)
RSpec/RepeatedExampleGroupBody:
  Enabled: false

# C: RSpec/RepeatedExampleGroupDescription: Repeated context block description on line(s)
RSpec/RepeatedExampleGroupDescription:
  Enabled: false

# C: [Correctable] RSpec/ScatteredLet: Group all let/let! blocks in the example group together.
RSpec/ScatteredLet:
  Enabled: false

対応したルール

RSpec/BeEq

C: [Correctable] RSpec/BeEq: Prefer be over eq.

spec/lib/tasks/user/destroy_spec.rb

-  expect(User.exists?(id: users)).to eq(false)
+  expect(User.exists?(id: users)).to be(false)

be_falseyを使わないのは、nilでもパスしてしまう為。

RSpec/NoExpectationExample

spec/routing/infomations_routing_spec.rb

C: RSpec/NoExpectationExample: No expectation found in this example.

spec/lib/tasks/all/destroy_spec.rb

   it '正常終了' do
-    subject
+    expect { subject }.not_to raise_error
   end

spec/routing/infomations_routing_spec.rb

-  it 'routes to #new' do
-    # expect(get: '/infomations/new').not_to be_routable # NOTE: infomations#show
-  end
+  # it 'routes to #new' do
+  #   expect(get: '/infomations/new').not_to be_routable # NOTE: infomations#show
+  # end

RSpec/ReceiveMessages

C: [Correctable] RSpec/ReceiveMessages: Use receive_messages instead of multiple stubs on lines

spec/helpers/application_helper_spec.rb

-  before do
-    allow(helper).to receive(:controller_name).and_return(controller_name)
-    allow(helper).to receive(:action_name).and_return(action_name)
-  end
+  before { allow(helper).to receive_messages(controller_name:, action_name:) }

RSpec/ChangeByZero

C: [Correctable] RSpec/ChangeByZero: Prefer not_to change over to change.by(0).

spec/requests/users/auth/registrations_spec.rb

-  expect { subject }.to change(User, :count).by(0) && change(ActionMailer::Base.deliveries, :count).by(0)
+  expect { subject }.not_to change(User, :count) && change(ActionMailer::Base.deliveries, :count)

RSpec/HookArgument

C: [Correctable] RSpec/HookArgument: Omit the default :each argument for RSpec hooks.

spec/rake_helper.rb

-  config.before(:each) do
+  config.before do

RSpec/DescribedClass

C: [Correctable] RSpec/DescribedClass: Use described_class instead of xxx.

spec/models/user_spec.rb

-  let(:current_user) { User.find(user.id) }
+  let(:current_user) { described_class.find(user.id) }

追加修正

let(:model) → subject(:model)

spec/models/user_spec.rb

-  let(:model) { FactoryBot.build_stubbed(:user, code:) }
+  subject(:model) { FactoryBot.build_stubbed(:user, code:) }

let(:mail) → subject(:mail)

spec/mailers/user_mailer_spec.rb

-  let(:mail) { UserMailer.with(user:).destroy_reserved }
+  subject(:mail) { described_class.with(user:).destroy_reserved }

subject do → subject {

好みもあるけど、4行が2行、5行が3行になるのと、見やすいかも。

spec/requests/users/auth/confirmations_spec.rb

-  subject do
-    headers = auth_headers.merge(accept_headers)
-    get user_auth_confirmation_path(format: subject_format, confirmation_token:, redirect_url: @redirect_url), headers:
-  end
+  subject { get user_auth_confirmation_path(format: subject_format, confirmation_token:, redirect_url: @redirect_url), headers: }
+  let(:headers) { auth_headers.merge(accept_headers) }

spec/helpers/application_helper_spec.rb

-  subject do
-    FactoryBot.create_list(:user, count)
-    models = User.page(page).per(2)
-    helper.first_page_number(models)
-  end
+  subject { helper.first_page_number(models) }
+  before { FactoryBot.create_list(:user, count) }
+  let(:models) { User.page(page).per(2) }

spec/models/user_spec.rb

-  subject do
-    user.cache_infomation_unread_count = nil
-    user.infomation_unread_count
-  end
+  subject { user.infomation_unread_count }
+  before { user.cache_infomation_unread_count = nil }

今回のコミット内容

origin RuboCopにRSpecのルールを導入、ルール調整

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です