ruby-on-railsruby-on-rails-5

Run tests in custom test folder in Rails 5+


When I want to run all model tests we do

rails test:models

If I similarly would like to run tests that sits in a folder called service_objects (in the test folder) - what would be the required steps?


With inspiration from multiple, sources I have tried the following in lib/tasks:

namespace :test do
  Rails::TestTask.new(classes: 'test:prepare') do |t|
    t.pattern = 'test/service_objects/**/*_test.rb'
  end
end

But running rails test:service_objects returns this error message:

NameError: uninitialized constant Rails::TestTask


Solution

  • Replace Rails::TestTask with Rails::TestUnit::Runner as shown in the file below, with the require path indicated at the top.

    Then to run ONLY the tests in test/focused directory, you can call

    rails test:focused
    

    and to run ALL tests in the test directory EXCEPT those in test/long_running, you can call

    rails test:without_long_running
    

    Tested with Rails 5.1.6

    The new Rails 5 test runner does have some really helpful features, but sometimes you still need a little more control.

    # lib/tasks/test_tasks.rake
    
    require "rails/test_unit/runner"
    
    namespace :test do
      task :focused => "test:prepare" do
        $: << "test"
        test_files = FileList['test/focused/*_test.rb']
        Rails::TestUnit::Runner.run(test_files)
      end
    
      task :without_long_running_tests => "test:prepare" do
        $: << "test"
        test_files = FileList['test/**/*_test.rb'].exclude('test/long_running/**/*_test.rb')
        Rails::TestUnit::Runner.run(test_files)
      end
    end
    

    Credit should go to jonatack may 2015 post here: https://github.com/rails/rails/issues/19997

    Update for Rails 7:

    namespace :test do
      task :without_long_running_tests => "test:prepare" do
        if !Rails.env.test?
          system("rails test:without_long_running_tests RAILS_ENV=test")
        else
          $: << "test"
          test_files = FileList['test/**/*_test.rb'].exclude('test/long_running/**/*_test.rb')
          Rails::TestUnit::Runner.run(test_files)
        end
      end
    end