### Example RuboCop Minitest Cop Configuration Source: https://github.com/rubocop/rubocop-minitest/blob/master/README.md Shows how to configure specific Minitest cops in the .rubocop.yml file, similar to standard RuboCop cops. This example excludes a specific file from the Minitest/AssertNil cop. ```yaml Minitest/AssertNil: Exclude: - test/my_file_to_ignore_test.rb ``` -------------------------------- ### Install rubocop-minitest Gem Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/installation.adoc Installs the rubocop-minitest gem directly using the RubyGems package manager. This is a straightforward method for users who prefer not to use a Gemfile. ```sh $ gem install rubocop-minitest ``` -------------------------------- ### Minitest Lifecycle Hooks Order Examples Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Ensures that Minitest lifecycle hooks (`setup`, `teardown`) are declared in the correct order of execution. Hooks should precede test methods and non-test case methods. The cop supports autocorrection. ```ruby # bad class FooTest < Minitest::Test def teardown; end def setup; end end # good class FooTest < Minitest::Test def setup; end def teardown; end end # bad (after test cases) class FooTest < Minitest::Test def test_something assert foo end def setup; end def teardown; end end # good class FooTest < Minitest::Test def setup; end def teardown; end def test_something assert foo end end # good (after non test case methods) class FooTest < Minitest::Test def do_something; end def setup; end def teardown; end end ``` -------------------------------- ### Install RuboCop Minitest via Gemfile Source: https://context7.com/rubocop/rubocop-minitest/llms.txt Add the rubocop-minitest gem to your Gemfile to include its functionality in your project. The 'require: false' option prevents eager loading, allowing RuboCop to manage its inclusion. ```ruby # Gemfile gem 'rubocop-minitest', require: false ``` -------------------------------- ### Readme Badges for RuboCop Minitest Usage Source: https://github.com/rubocop/rubocop-minitest/blob/master/README.md Markdown snippets for adding badges to a project's README file to indicate the use of RuboCop Minitest and adherence to the Minitest Style Guide. ```markdown [![Minitest Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop-minitest) ``` ```markdown [![Minitest Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://minitest.rubystyle.guide) ``` -------------------------------- ### Add rubocop-minitest to Gemfile Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/installation.adoc Adds the rubocop-minitest gem to your project's Gemfile for management with Bundler. This ensures consistent gem versions across your project and development environments. ```ruby gem 'rubocop-minitest', require: false ``` -------------------------------- ### Enforcing Minitest Lifecycle Hooks Order Source: https://context7.com/rubocop/rubocop-minitest/llms.txt This RuboCop cop ensures that Minitest lifecycle hooks (`setup`, `teardown`, `before_suite`, `after_suite`) are declared in their correct execution order. It provides examples of 'bad' code with out-of-order hooks and 'good' code with hooks correctly sequenced. ```ruby # Bad - hooks declared out of execution order class MyTest < Minitest::Test def teardown cleanup_database end def setup initialize_database end end # Good - hooks in execution order class MyTest < Minitest::Test def setup @db = Database.new @db.connect @user = User.create(name: 'Test User') end def teardown @user.destroy if @user @db.disconnect @db = nil end def test_user_operations assert_equal('Test User', @user.name) end end # Multiple hook types in correct order class IntegrationTest < Minitest::Test def self.before_suite Rails.application.load_seed end def setup @connection = ApiClient.connect end def teardown @connection.close end def self.after_suite Database.cleanup end end ``` -------------------------------- ### Rake Task Configuration for RuboCop Minitest Source: https://github.com/rubocop/rubocop-minitest/blob/master/README.md Example of configuring RuboCop to load the Minitest extension within a Rake task. This involves requiring the RuboCop::RakeTask and adding 'rubocop-minitest' to the task's plugins. ```ruby require 'rubocop/rake_task' RuboCop::RakeTask.new do |task| task.plugins << 'rubocop-minitest' end ``` -------------------------------- ### Load Minitest Plugin via RuboCop Command Line Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/usage.adoc This shell command shows how to load the RuboCop Minitest extension directly from the command line using the --plugin flag. This is a convenient way to temporarily enable the Minitest cops without modifying configuration files. ```sh $ rubocop --plugin rubocop-minitest ``` -------------------------------- ### Minitest Assert Nil Cop Examples Source: https://context7.com/rubocop/rubocop-minitest/llms.txt The Assert Nil cop enforces the use of `assert_nil` for checking if a value is nil, promoting conciseness over verbose equality checks. Examples show incorrect and correct assertion styles. ```ruby # Bad - verbose equality check assert_equal(nil, user.email) assert_equal(nil, response.body, 'Response body should be nil') assert(user.deleted_at.nil?) assert_predicate(result, :nil?) # Good - concise nil assertion assert_nil(user.email) assert_nil(response.body, 'Response body should be nil') # In a test class class UserTest < Minitest::Test def test_uninitialized_user_has_no_email user = User.new assert_nil(user.email) end def test_deleted_user_has_deletion_timestamp user = User.find(1) user.delete refute_nil(user.deleted_at) end end ``` -------------------------------- ### Minitest Assert Equal Cop Examples Source: https://context7.com/rubocop/rubocop-minitest/llms.txt The Assert Equal cop encourages the use of `assert_equal` for all equality comparisons, replacing direct operator checks within `assert`. This ensures clear and consistent assertion messages. ```ruby # Bad - using equality operator in assert assert("rubocop-minitest" == gem_name) assert(expected_count == actual_count) assert_operator("ruby", :==, language) # Good - using assert_equal assert_equal("rubocop-minitest", gem_name) assert_equal(expected_count, actual_count) assert_equal("ruby", language) # Complete test example with proper error handling class CalculatorTest < Minitest::Test def setup @calculator = Calculator.new end def test_addition result = @calculator.add(5, 3) assert_equal(8, result, 'Addition should return correct sum') end def test_division_by_zero assert_raises(ZeroDivisionError) do @calculator.divide(10, 0) end end def test_multiple_operations result = @calculator.add(10, 5) assert_equal(15, result) result = @calculator.multiply(result, 2) assert_equal(30, result) end end ``` -------------------------------- ### Minitest Refute Nil Cop Examples Source: https://context7.com/rubocop/rubocop-minitest/llms.txt The Refute Nil cop promotes the use of `refute_nil` for asserting that a value is not nil, simplifying negative assertions. It contrasts with verbose checks using `refute_equal` or `refute` with `.nil?`. ```ruby # Bad - checking non-nil with equality refute_equal(nil, user.name) refute(session.token.nil?) refute_predicate(response, :nil?) # Good - using refute_nil refute_nil(user.name) refute_nil(session.token, 'Session token should exist') # Real-world authentication test class AuthenticationTest < Minitest::Test def test_successful_login_creates_token user = User.create(email: 'test@example.com', password: 'secret') session = AuthService.login('test@example.com', 'secret') refute_nil(session) refute_nil(session.token) refute_nil(session.expires_at) assert_equal(user.id, session.user_id) end def test_failed_login_returns_nil session = AuthService.login('wrong@example.com', 'wrong') assert_nil(session) end end ``` -------------------------------- ### Configure RuboCop to Load Minitest Plugin (.rubocop.yml) Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/usage.adoc This YAML snippet demonstrates how to configure RuboCop to automatically load the Minitest extension by adding 'rubocop-minitest' to the 'plugins' list in your .rubocop.yml file. This method requires RuboCop version 1.72+. ```yaml plugins: rubocop-minitest ``` -------------------------------- ### Minitest No Test Cases Examples Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Checks if a Minitest test class contains any actual test cases (methods starting with `test_` or equivalent). This cop is disabled by default and does not support autocorrection. ```ruby # bad class FooTest < Minitest::Test def do_something end end ``` -------------------------------- ### Require Minitest Plugin in Older RuboCop Versions Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/usage.adoc For RuboCop versions earlier than 1.72, the 'plugins' configuration is not supported. Instead, you must use the 'require' directive in your .rubocop.yml file to load the Minitest extension. ```yaml require: rubocop-minitest ``` -------------------------------- ### Minitest No Assertions Examples Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Ensures that test cases contain at least one assertion call. This cop treats matchers like `must_equal` and `wont_match` as assertion methods. It applies to both standard Minitest and ActiveSupport::TestCase. ```ruby # bad class FooTest < Minitest::Test def test_the_truth end end # good class FooTest < Minitest::Test def test_the_truth assert true end end # bad class FooTest < ActiveSupport::TestCase describe 'foo' do it 'test equal' do end end end # good class FooTest < ActiveSupport::TestCase describe 'foo' do it 'test equal' do musts.must_equal expected_musts end end end ``` -------------------------------- ### Minitest: Test method naming convention Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Enforces that Minitest test methods start with the `test_` prefix. This convention is crucial for Minitest to discover and run tests automatically. Methods not following this prefix are assumed to be helper methods. ```ruby # good class FooTest < Minitest::Test def test_does_something assert_equal 42, do_something end end # good class FooTest < Minitest::Test def helper_method(argument) end end # bad # class FooTest < Minitest::Test # def does_something # assert_equal 42, do_something # end # end ``` -------------------------------- ### Use assert_output for Minitest Output Checks Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule guides users towards `assert_output` for capturing and asserting standard output in Minitest. It replaces manual redirection of `$stdout` with `StringIO`. This improves test readability and maintainability when checking program output. ```ruby # bad $stdout = StringIO.new puts object.method $stdout.rewind assert_match expected, $stdout.read # good assert_output(expected) { puts object.method } ``` -------------------------------- ### Minitest Literal As Actual Argument Examples Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Enforces the correct order of expected and actual arguments for `assert_equal` in Minitest. The expected value should typically be the first argument and the actual value the second. This cop supports autocorrection. ```ruby # bad assert_equal foo, 2 assert_equal foo, [1, 2] assert_equal foo, [1, 2], 'message' # good assert_equal 2, foo assert_equal [1, 2], foo assert_equal [1, 2], foo, 'message' ``` -------------------------------- ### Using assert_empty for Minitest Emptiness Checks Source: https://context7.com/rubocop/rubocop-minitest/llms.txt This RuboCop cop encourages the use of `assert_empty` for checking if collections or arrays are empty, instead of using `assert(collection.empty?)`. Examples show the 'bad' practice and the 'good' practice using `assert_empty`. ```ruby # Bad - using empty? in assert assert(array.empty?) assert(collection.empty?, 'Collection should be empty') # Good - using assert_empty assert_empty(array) assert_empty(collection, 'Collection should be empty') # Testing collection state class CollectionStateTest < Minitest::Test def test_new_cart_is_empty cart = ShoppingCart.new assert_empty(cart.items) end def test_filter_returns_empty_for_no_matches products = Product.all filtered = products.filter { |p| p.price > 1000000 } assert_empty(filtered) end def test_clearing_collection list = TodoList.new list.add('Task 1') list.add('Task 2') refute_empty(list.items) list.clear assert_empty(list.items) end end ``` -------------------------------- ### Integrate RuboCop Minitest with Rake Tasks Source: https://context7.com/rubocop/rubocop-minitest/llms.txt Incorporate RuboCop Minitest into your project's Rake tasks for convenient execution. This setup allows you to run RuboCop checks with specific patterns and options, and to fail the build on errors. ```ruby # Rakefile require 'rubocop/rake_task' RuboCop::RakeTask.new do |task| task.plugins << 'rubocop-minitest' task.patterns = ['test/**/*_test.rb'] task.options = ['--display-cop-names'] task.fail_on_error = true end # Run with: rake rubocop ``` -------------------------------- ### Load Minitest Plugin using RuboCop Rake Task Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/usage.adoc This Ruby code snippet illustrates how to configure RuboCop to load the Minitest plugin within a Rake task. By appending 'rubocop-minitest' to the task's plugins, you can ensure the Minitest cops are active during Rake-based builds. ```ruby RuboCop::RakeTask.new do |task| task.plugins << 'rubocop-minitest' end ``` -------------------------------- ### Minitest Assert Includes Cop Examples Source: https://context7.com/rubocop/rubocop-minitest/llms.txt The Assert Includes cop enforces the use of `assert_includes` for checking if an item is present within a collection. This is preferred over using `collection.include?` within an `assert` statement. ```ruby # Bad - using include? in assert assert(collection.include?(item)) assert([1, 2, 3].include?(search_value)) # Good - using assert_includes assert_includes(collection, item) assert_includes([1, 2, 3], search_value) ``` -------------------------------- ### Enforcing `assert_respond_to` for Method Existence Checks in Minitest Source: https://context7.com/rubocop/rubocop-minitest/llms.txt The Assert Respond To Cop guides developers to use `assert_respond_to` for checking if an object responds to a specific method, providing a more explicit alternative to using `assert` with `respond_to?`. This improves test readability and intent. ```ruby # Bad - using respond_to? in assert assert(object.respond_to?(:save)) assert(user.respond_to?(:authenticate)) # Good - using assert_respond_to assert_respond_to(object, :save) assert_respond_to(user, :authenticate) ``` -------------------------------- ### Avoid assertions in Minitest lifecycle hooks Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule checks for the presence of assertions within Minitest lifecycle hook methods such as `setup` or `teardown`. Assertions should typically reside in test methods, not in setup or teardown, to maintain clear separation of concerns and test structure. ```ruby # bad class FooTest < Minitest::Test def setup assert_equal(foo, bar) end end ``` -------------------------------- ### Add Minitest/AssertionInLifecycleHook Cop Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Adds the `Minitest/AssertionInLifecycleHook` cop to prevent accidental or inappropriate use of assertions within Minitest's lifecycle hook methods (e.g., `setup`, `teardown`). ```ruby # Example of code that would be flagged by Minitest/AssertionInLifecycleHook def setup assert true end # Corrected version (assertion moved out of setup) ``` -------------------------------- ### Use refute_match for String Pattern Matching in Minitest Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule guides developers to use `refute_match` for negating regular expression matches on strings, instead of `refute(matcher.match(string))`, `refute(matcher =~ string)`, or `refute_operator`. It simplifies and clarifies assertions about string content. This applies to Ruby Minitest test suites. ```ruby # bad refute(matcher.match(string)) refute(matcher.match?(string)) refute(matcher =~ string) refute_operator(matcher, :=~, string) assert_operator(matcher, :!~, string) refute(matcher.match(string), 'message') # good refute_match(matcher, string) refute_match(matcher, string, 'message') ``` -------------------------------- ### Enforcing `assert_match` for Regex Matching in Minitest Source: https://context7.com/rubocop/rubocop-minitest/llms.txt The Assert Match Cop encourages the use of `assert_match` for regular expression assertions in Minitest, replacing the less direct approach of using `assert` with the `match` method. Examples cover email validation, phone number formats, and log message parsing. ```ruby # Bad - using match in assert assert(pattern.match(string)) assert(/d{3}-d{4}/.match(phone_number)) # Good - using assert_match assert_match(pattern, string) assert_match(/d{3}-d{4}/, phone_number) # Pattern matching in validation tests class ValidationTest < Minitest::Test def test_email_format_validation valid_email = 'user@example.com' invalid_email = 'invalid.email' assert_match(/A[w+-.]+@[a-zd-]+(.[a-zd-]+)*.[a-z]+z/i, valid_email) refute_match(/A[w+-.]+@[a-zd-]+(.[a-zd-]+)*.[a-z]+z/i, invalid_email) end def test_phone_number_formats us_phone = '555-1234' intl_phone = '+1-555-1234' assert_match(/d{3}-d{4}/, us_phone) assert_match(/+d{1,3}-d{3}-d{4}/, intl_phone) end def test_log_message_contains_timestamp log_entry = Logger.format_message('Error occurred') assert_match(/[d{4}-d{2}-d{2} d{2}:d{2}:d{2}]/, log_entry) assert_match(/Error occurred/, log_entry) end end ``` -------------------------------- ### Minitest Multiple Assertions Example (Max: 1) Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Checks if test cases contain an excessive number of assertion calls. The maximum allowed assertion calls is configurable. If conditional code with assertions is present, the branch with the maximum assertions is counted. The default maximum is 3. ```ruby # bad class FooTest < Minitest::Test def test_asserts_twice assert_equal(42, do_something) assert_empty(array) end end # good class FooTest < Minitest::Test def test_asserts_once assert_equal(42, do_something) end def test_another_asserts_once assert_empty(array) end end ``` -------------------------------- ### Minitest: Test file naming convention Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Enforces that Minitest test files follow a naming convention, either starting with `test_` or ending with `_test.rb`. This helps in organizing test files and ensuring they are discovered correctly. It checks files that define classes ending with `Test`. ```ruby # good my_class_test.rb test_my_class.rb # bad # my_class.rb ``` -------------------------------- ### Enforcing `assert_instance_of` for Type Checking in Minitest Source: https://context7.com/rubocop/rubocop-minitest/llms.txt The Assert Instance Of Cop promotes the use of `assert_instance_of` over `instance_of?` within assertions for clearer and more idiomatic type checking in Minitest. It provides examples for basic type verification and checks within factory or API response scenarios. ```ruby # Bad - using instance_of? in assert assert(user.instance_of?(User)) assert(response.instance_of?(Hash)) # Good - using assert_instance_of assert_instance_of(User, user) assert_instance_of(Hash, response) # Type checking in object factory tests class FactoryTest < Minitest::Test def test_user_factory_creates_correct_instance user = UserFactory.create assert_instance_of(User, user) refute_instance_of(AdminUser, user) end def test_polymorphic_response_handling json_response = ApiClient.get('/users/1', format: :json) xml_response = ApiClient.get('/users/1', format: :xml) assert_instance_of(Hash, json_response) assert_instance_of(Nokogiri::XML::Document, xml_response) end def test_inheritance_hierarchy admin = AdminUser.new assert_instance_of(AdminUser, admin) assert_kind_of(User, admin) # checks inheritance end end ``` -------------------------------- ### Configure RuboCop to Load Minitest Extension Source: https://github.com/rubocop/rubocop-minitest/blob/master/README.md Demonstrates how to configure RuboCop to load the Minitest extension. This can be done using the 'plugins' directive in .rubocop.yml or via the command line. For older RuboCop versions (pre-1.72), 'require' should be used instead of 'plugins'. ```yaml plugins: rubocop-minitest ``` ```yaml plugins: - rubocop-other-extension - rubocop-minitest ``` ```shell $ rubocop --plugin rubocop-minitest ``` -------------------------------- ### Run RuboCop with Minitest Plugin via Command Line Source: https://context7.com/rubocop/rubocop-minitest/llms.txt Execute RuboCop with the Minitest plugin using the command line. Options include auto-correcting violations (-A) and specifying files or directories to check. ```bash # Run RuboCop with Minitest plugin rubocop --plugin rubocop-minitest # Auto-correct violations rubocop --plugin rubocop-minitest -A # Check specific files rubocop --plugin rubocop-minitest test/**/*_test.rb ``` -------------------------------- ### Add Minitest/AssertInDelta and Minitest/RefuteInDelta Cops Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Introduces `Minitest/AssertInDelta` and `Minitest/RefuteInDelta` cops to encourage the use of `assert_in_delta` and `refute_in_delta` for floating-point comparisons, promoting precision and clarity. ```ruby # Example of code that would be flagged by Minitest/AssertInDelta assert_equal 1.0, 1.0000001 # Corrected version assert_in_delta 1.0, 1.0000001, 0.00001 ``` -------------------------------- ### Add AssertPathExists and RefutePathExists Cops Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Introduces `AssertPathExists` and `RefutePathExists` cops to promote the use of dedicated Minitest assertion methods (`assert_path_exists`, `refute_path_exists`) over manual checks with `File.exist?`, simplifying file system assertions. ```ruby # Example of code that would be flagged by AssertPathExists assert File.exist?("/path/to/file") # Corrected version assert_path_exists "/path/to/file" ``` -------------------------------- ### Testing Array and Hash Membership with Minitest Source: https://context7.com/rubocop/rubocop-minitest/llms.txt Demonstrates how to test for the presence or absence of elements within arrays and hashes using Minitest's `assert_includes` and `refute_includes` methods. These methods are useful for verifying collection contents and hash key/value pairings. ```ruby class CollectionTest < Minitest::Test def test_array_contains_expected_values fruits = ['apple', 'banana', 'orange'] assert_includes(fruits, 'banana') refute_includes(fruits, 'grape') end def test_hash_keys_and_values config = { host: 'localhost', port: 3000, ssl: true } assert_includes(config.keys, :host) assert_includes(config.values, 3000) assert_equal(true, config[:ssl]) end def test_user_roles_authorization admin = User.new(roles: ['admin', 'editor', 'viewer']) assert_includes(admin.roles, 'admin') guest = User.new(roles: ['viewer']) refute_includes(guest.roles, 'admin') end end ``` -------------------------------- ### Add AssertKindOf and RefuteKindOf Cops Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Introduces `AssertKindOf` and `RefuteKindOf` cops to promote the use of `assert_kind_of` and `refute_kind_of` over manual type checks with `kind_of?`, simplifying type assertions. ```ruby # Example of code that would be flagged by AssertKindOf assert "hello".kind_of?(String) # Corrected version assert_kind_of String, "hello" ``` -------------------------------- ### Add Minitest/AssertOutput Cop Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Adds the `Minitest/AssertOutput` cop to encourage the use of `assert_output` for verifying the output of code blocks to STDOUT and STDERR, ensuring predictable program behavior. ```ruby # Example of code that would be flagged by Minitest/AssertOutput output = capture_stdout { puts "hello" } assert_equal "hello\n", output # Corrected version assert_output "hello\n" do puts "hello" end ``` -------------------------------- ### Configure RuboCop Minitest in .rubocop.yml Source: https://context7.com/rubocop/rubocop-minitest/llms.txt Enable the rubocop-minitest plugin and configure specific Minitest cops within your .rubocop.yml configuration file. This allows for fine-grained control over style enforcement. ```yaml # .rubocop.yml plugins: - rubocop-minitest # Configure specific cops Minitest/AssertNil: Enabled: true Minitest/GlobalExpectations: EnforcedStyle: any Minitest/MultipleAssertions: Enabled: true Max: 3 ``` -------------------------------- ### Testing API Interface Compliance with Minitest Source: https://context7.com/rubocop/rubocop-minitest/llms.txt This snippet demonstrates how to test if objects implement required methods using Minitest's `assert_respond_to`. It covers testing user, cache, and storage interfaces, highlighting Duck Typing compatibility. ```ruby class InterfaceTest < Minitest::Test def test_user_implements_required_methods user = User.new assert_respond_to(user, :save) assert_respond_to(user, :update) assert_respond_to(user, :destroy) assert_respond_to(user, :authenticate) end def test_cache_adapter_interface cache = CacheAdapter.new(:redis) assert_respond_to(cache, :get) assert_respond_to(cache, :set) assert_respond_to(cache, :delete) assert_respond_to(cache, :clear) refute_respond_to(cache, :internal_method) end def test_duck_typing_compatibility file_storage = FileStorage.new s3_storage = S3Storage.new [file_storage, s3_storage].each do |storage| assert_respond_to(storage, :upload) assert_respond_to(storage, :download) assert_respond_to(storage, :delete) end end end ``` -------------------------------- ### Use assert_same for identity comparison Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule promotes the use of `assert_same(expected, actual)` for comparing object identity, rather than `assert(expected.equal?(actual))` or comparing object IDs. It's crucial to use `assert_same` only when identity is the specific concern, otherwise `assert_equal` should be preferred. ```ruby # bad assert(expected.equal?(actual)) assert_equal(expected.object_id, actual.object_id) # good assert_same(expected, actual) ``` -------------------------------- ### Add Minitest/AssertSilent Cop Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Introduces the `Minitest/AssertSilent` cop to check for the correct usage of `assert_silent`, which verifies that a block of code produces no output to STDOUT or STDERR. ```ruby # Example of code that would be flagged by Minitest/AssertSilent assert_output "", "", "some_command" # Corrected version assert_silent { some_command } ``` -------------------------------- ### Use assert_respond_to over object.respond_to? Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule encourages the use of `assert_respond_to(object, :method)` instead of `assert(object.respond_to?(:method))`. The former is more explicit and readable for checking if an object responds to a specific method. It supports an optional message argument. ```ruby # bad assert(object.respond_to?(:do_something)) assert(object.respond_to?(:do_something), 'message') assert(respond_to?(:do_something)) # good assert_respond_to(object, :do_something) assert_respond_to(object, :do_something, 'message') assert_respond_to(self, :do_something) ``` -------------------------------- ### Minitest/NonPublicTestMethod: Detect non-public Minitest test methods Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop identifies test methods that are not public (i.e., marked as private or protected). Minitest only executes public test methods. Examples show how to correctly define public test methods and differentiate them from non-test methods or methods without assertions. ```ruby # bad class FooTest private # or protected def test_does_something assert_equal 42, do_something end end # good class FooTest def test_does_something assert_equal 42, do_something end end # good (not a test case name) class FooTest private # or protected def does_something assert_equal 42, do_something end end # good (no assertions) class FooTest private # or protected def test_does_something do_something end end ``` -------------------------------- ### Enforcing Focused Tests: Minitest Multiple Assertions Cop Source: https://context7.com/rubocop/rubocop-minitest/llms.txt This RuboCop cop detects tests with excessive assertion counts, promoting the practice of splitting large tests into smaller, more focused ones. It shows examples of 'bad' code with too many assertions and 'good' code refactored into separate, dedicated tests. ```ruby # Bad - too many assertions in one test (Max: 3) def test_user_creation_with_everything user = User.create(name: 'John', email: 'john@example.com') assert_equal('John', user.name) assert_equal('john@example.com', user.email) refute_nil(user.id) refute_nil(user.created_at) assert_equal('active', user.status) end # Good - split into focused tests class UserCreationTest < Minitest::Test def setup @user = User.create(name: 'John', email: 'john@example.com') end def test_sets_user_name_and_email assert_equal('John', @user.name) assert_equal('john@example.com', @user.email) end def test_generates_id_and_timestamp refute_nil(@user.id) refute_nil(@user.created_at) end def test_sets_default_active_status assert_equal('active', @user.status) end end # Configuration in .rubocop.yml # Minitest/MultipleAssertions: # Enabled: true # Max: 3 ``` -------------------------------- ### Use assert_path_exists for Minitest File Path Checks Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Encourages the use of `assert_path_exists` in Minitest for verifying the existence of file paths, replacing `assert(File.exist?(path))`. This provides a more semantic and readable way to check for file or directory existence. It accepts an optional message. ```ruby # bad assert(File.exist?(path)) assert(File.exist?(path), 'message') # good assert_path_exists(path) assert_path_exists(path, 'message') ``` -------------------------------- ### Add Minitest/AssertPredicate and Minitest/RefutePredicate Cops Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.18.0.md Introduces new cops to enforce the use of `assert_predicate` and `refute_predicate` for checking predicate methods. This helps maintain consistency and readability in Minitest assertions. ```ruby # Example of Minitest/AssertPredicate usage (conceptual): assert_predicate obj, :truthy? ``` ```ruby # Example of Minitest/RefutePredicate usage (conceptual): refute_predicate obj, :falsy? ``` -------------------------------- ### Minitest/RefuteEmpty: Use refute_empty instead of refute(object.empty?) Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop enforces the use of the more idiomatic `refute_empty` method instead of combining `refute` with `object.empty?`. This improves readability and consistency in Minitest test suites. ```ruby # bad refute(object.empty?) refute(object.empty?, 'message') # good refute_empty(object) refute_empty(object, 'message') ``` -------------------------------- ### Minitest/AssertIncludes: Use assert_includes instead of assert(collection.include?) Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Promotes the use of `assert_includes` for checking if an object is present in a collection, replacing `assert(collection.include?(object))`. This leads to more expressive and readable test code. It is always enabled and supports autocorrection. ```ruby # bad assert(collection.include?(object)) assert(collection.include?(object), 'message') # good assert_includes(collection, object) assert_includes(collection, object, 'message') ``` -------------------------------- ### Use assert_silent for suppressing output Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule enforces the use of `assert_silent { ... }` to test code that should not produce any output (stdout or stderr). It is preferred over `assert_output('', '') { ... }` for clarity and conciseness when the goal is simply to assert silence. ```ruby # bad assert_output('', '') { puts object.do_something } # good assert_silent { puts object.do_something } ``` -------------------------------- ### Minitest/AssertMatch: Use assert_match for pattern matching Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop enforces the use of `assert_match` for pattern matching assertions, replacing `assert(matcher.match(string))`. It promotes clearer and more idiomatic Minitest syntax for pattern matching checks. Always enabled and supports autocorrection. ```ruby # bad assert(matcher.match(string)) # good assert_match(matcher, string) ``` -------------------------------- ### Minitest/RefuteFalse: Use refute for boolean false assertions Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop encourages using `refute(object)` for asserting that an object is false, instead of `assert_equal(false, object)` or `assert(!object)`. Note that this cop is marked as unsafe because it cannot reliably detect failures when the second argument to `assert_equal` is `nil`. ```ruby # bad assert_equal(false, actual) assert_equal(false, actual, 'message') assert(!test) assert(!test, 'message') ``` -------------------------------- ### Minitest/AssertEmpty: Use assert_empty instead of assert(object.empty?) Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop enforces the use of `assert_empty` for checking if a collection is empty, replacing the more verbose `assert(object.empty?)` pattern. It supports autocorrection and is always enabled. Recommended for cleaner and more readable tests. ```ruby # bad assert(object.empty?) assert(object.empty?, 'message') # good assert_empty(object) assert_empty(object, 'message') ``` -------------------------------- ### Require RuboCop 0.87 or Higher Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Updates the minimum required version for RuboCop to 0.87 or higher. This change ensures compatibility with newer RuboCop features and internal APIs. ```ruby # Gemfile entry example gem "rubocop-minitest", require: false gem "rubocop", ">= 0.87.0" ``` -------------------------------- ### Add Minitest/MultipleAssertions Cop Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Adds the `Minitest/MultipleAssertions` cop to help identify and refactor test methods that contain too many assertions, encouraging tests to focus on a single behavior. ```ruby # Example of code that would be flagged by Minitest/MultipleAssertions def test_user_creation assert_equal "John Doe", user.name assert_equal 30, user.age assert_equal "john@example.com", user.email end # Potentially refactored version with separate tests for each assertion ``` -------------------------------- ### Minitest/AssertEqual: Use assert_equal over assert(expected == actual) Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Enforces the use of `assert_equal(expected, actual)` instead of `assert(expected == actual)` or `assert_operator(expected, :==, actual)`. This cop improves clarity and test readability. It is always enabled and supports autocorrection. ```ruby # bad assert("rubocop-minitest" == actual) assert_operator("rubocop-minitest", :==, actual) # good assert_equal("rubocop-minitest", actual) ``` -------------------------------- ### Use assert_raises with block for exception handling Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule enforces the use of `assert_raises` with a block to catch and assert on raised exceptions. It is preferred over manual exception handling with `assert_match` on the exception message. This promotes clearer and more idiomatic Minitest code. ```ruby exception = assert_raises FooError do obj.occur_error end assert_match(/some message/, exception.message) ``` -------------------------------- ### Enforce Minitest refute_path_exists Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop enforces the use of `refute_path_exists` instead of `refute(File.exist?(path))`. It ensures that tests for file existence checks are written using the dedicated Minitest method for better readability and maintainability. ```ruby refute(File.exist?(path)) refute(File.exist?(path), 'message') ``` ```ruby refute_path_exists(path) refute_path_exists(path, 'message') ``` -------------------------------- ### Use assert_equal for expected vs. actual comparisons Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule aims to detect when `assert` is used in a way that suggests `assert_equal` was intended, particularly when two arguments that look like expected and actual values are provided. The second argument, if named `message` or `msg`, is permitted. This cop is unsafe because it cannot definitively distinguish between a message and an actual value. ```ruby # bad assert(3, my_list.length) assert(expected, actual) # good assert_equal(3, my_list.length) assert_equal(expected, actual) assert(foo, 'message') assert(foo, message) assert(foo, msg) ``` -------------------------------- ### Add Minitest/UnspecifiedException Cop Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Implements the `Minitest/UnspecifiedException` cop to detect and flag tests that do not specify the type of exception being rescued, promoting more robust error handling checks. ```ruby # Example of code that would be flagged by Minitest/UnspecifiedException assert_raises { raise "error" } # Corrected version assert_raises(RuntimeError) { raise "error" } ``` -------------------------------- ### Use assert_match for Minitest String Matching Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule encourages the use of `assert_match` for string matching operations in Minitest tests. It helps avoid less expressive methods like `assert` with various matchers. This is applicable when checking if a string matches a given pattern or matcher. ```ruby # bad assert(matcher.match(string)) assert(matcher.match?(string)) assert(matcher =~ string) assert_operator(matcher, :=~, string) assert(matcher.match(string), 'message') # good assert_match(regex, string) assert_match(matcher, string, 'message') ``` -------------------------------- ### Add Minitest/TestMethodName Cop Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.10.0.md Implements the `Minitest/TestMethodName` cop to enforce consistent naming conventions for Minitest test methods, improving readability and maintainability of test suites. ```ruby # Example of a test method name that might be flagged by Minitest/TestMethodName def test_something_works assert true end # Potentially corrected version based on configured naming convention ``` -------------------------------- ### Enforce Minitest refute_respond_to Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop enforces the use of `refute_respond_to(object, :do_something)` over `refute(object.respond_to?(:do_something))`. It provides a more direct and readable way to assert that an object does not respond to a specific method. ```ruby refute(object.respond_to?(:do_something)) refute(object.respond_to?(:do_something), 'message') refute(respond_to?(:do_something)) ``` ```ruby refute_respond_to(object, :do_something) refute_respond_to(object, :do_something, 'message') refute_respond_to(self, :do_something) ``` -------------------------------- ### Minitest/RefuteEqual: Enforce refute_equal for inequality checks Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop promotes the use of `refute_equal(expected, object)` over less direct methods like `assert(expected != actual)` or `assert_operator(expected, :!=, actual)`. It simplifies inequality assertions. ```ruby # bad assert("rubocop-minitest" != actual) refute("rubocop-minitest" == actual) assert_operator("rubocop-minitest", :!=, actual) refute_operator("rubocop-minitest", :==, actual) # good refute_equal("rubocop-minitest", actual) ``` -------------------------------- ### Minitest/AssertInDelta: Use assert_in_delta for float comparisons Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop encourages using `assert_in_delta` for comparing floating-point numbers, replacing `assert_equal` for such cases. It helps manage potential precision issues. This cop is pending and supports autocorrection. ```ruby # bad assert_equal(0.2, actual) assert_equal(0.2, actual, 'message') # good assert_in_delta(0.2, actual) assert_in_delta(0.2, actual, 0.001, 'message') ``` -------------------------------- ### Use refute_instance_of for Class Type Checks in Minitest Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule encourages the use of `refute_instance_of(Class, object)` instead of `refute(object.instance_of?(Class))` or `refute_equal(Class, object.class)`. It provides a more direct and expressive way to assert that an object is not an instance of a specific class. Applicable to Ruby tests with Minitest. ```ruby # bad refute(object.instance_of?(Class)) refute(object.instance_of?(Class), 'message') # bad refute_equal(Class, object.class) refute_equal(Class, object.class, 'message') # good refute_instance_of(Class, object) refute_instance_of(Class, object, 'message') ``` -------------------------------- ### Enforce Minitest refute_same Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop enforces the use of `refute_same(expected, object)` over `refute(expected.equal?(actual))`. It ensures that identity comparisons are explicitly stated using `refute_same`, reserving `refute_equal` for value comparisons. ```ruby refute(expected.equal?(actual)) refute_equal(expected.object_id, actual.object_id) ``` ```ruby refute_same(expected, actual) ``` -------------------------------- ### Enhance Minitest/AssertNil for assert_predicate Source: https://github.com/rubocop/rubocop-minitest/blob/master/relnotes/v0.18.0.md Updates the `Minitest/AssertNil` and `Minitest/RefuteNil` cops to recognize and flag incorrect usage when `assert_predicate` or `refute_predicate` with a nil check are employed. This promotes the idiomatic use of `assert_nil` and `refute_nil`. ```ruby # Incorrect usage to be flagged by enhanced cop: assert_predicate obj, :nil? refute_predicate obj, :nil? ``` ```ruby # Correct usage: assert_nil obj refute_nil obj ``` -------------------------------- ### Enforcing Consistent Expectation Wrappers in Minitest Source: https://context7.com/rubocop/rubocop-minitest/llms.txt This section details the Global Expectations Cop, which enforces consistent use of expectation wrappers like `_`, `expect`, or `value` in Minitest spec syntax. It shows deprecated global expectations and the preferred, standardized alternatives. ```ruby # Bad - deprecated global expectations users.must_equal expected_users result.wont_match /error/ proc { raise_error }.must_raise TypeError # Good - using underscore wrapper (default style) _(users).must_equal expected_users _(result).wont_match /error/ _ { raise_error }.must_raise TypeError # Good - using expect wrapper (when EnforcedStyle: expect) expect(users).must_equal expected_users expect(result).wont_match /error/ expect { raise_error }.must_raise TypeError # Good - using value wrapper (when EnforcedStyle: value) value(users).must_equal expected_users value(result).wont_match /error/ value { raise_error }.must_raise TypeError # Complete spec-style test describe Calculator do before do @calc = Calculator.new end it 'performs addition correctly' do result = @calc.add(5, 3) _(result).must_equal 8 end it 'raises error on invalid input' do _ { @calc.divide('invalid', 2) }.must_raise ArgumentError end it 'handles negative numbers' do result = @calc.multiply(-5, 3) _(result).must_equal(-15) _(result).must_be :<, 0 end end ``` -------------------------------- ### Minitest/AssertInstanceOf: Use assert_instance_of for class checks Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This cop enforces the use of `assert_instance_of(Class, object)` over `assert(object.instance_of?(Class))` or `assert_equal(Class, object.class)`. It provides a clearer way to assert the exact class of an object. Always enabled and supports autocorrection. ```ruby # bad assert(object.instance_of?(Class)) assert(object.instance_of?(Class), 'message') # bad assert_equal(Class, object.class) assert_equal(Class, object.class, 'message') # good assert_instance_of(Class, object) assert_instance_of(Class, object, 'message') ``` -------------------------------- ### Use assert_operator for Minitest Comparisons Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc Promotes the use of `assert_operator(expected, operator, actual)` over the less explicit `assert(expected operator actual)` in Minitest. This rule makes comparisons clearer and more intention-revealing. It handles various comparison operators. ```ruby # bad assert(expected < actual) # good assert_operator(expected, :<, actual) ``` -------------------------------- ### Use refute_nil for Nil Assertions in Minitest Source: https://github.com/rubocop/rubocop-minitest/blob/master/docs/modules/ROOT/pages/cops_minitest.adoc This rule promotes the use of `refute_nil` for asserting that a value is not nil. It replaces less direct methods like `refute_equal(nil, something)`, `refute(something.nil?)`, or `refute_predicate(something, :nil?)`, leading to more concise and readable tests. This is relevant for Ruby Minitest code. ```ruby # bad refute_equal(nil, actual) refute_equal(nil, actual, 'message') refute(actual.nil?) refute(actual.nil?, 'message') refute_predicate(object, :nil?) refute_predicate(object, :nil?, 'message') # good refute_nil(actual) refute_nil(actual, 'message') ```