Ruby on Rails 6 with Minitest: 出力されるエラーを短縮する方法はありますか?

概要

Michael Hartl 著の『Ruby on Rails チュートリアル』のセクション 3.3 を読んでいますが、テストに関するセクションが始まったばかりです。このセクションでは、静的ページをコントローラー (StaticPagesController) にグループ化し、コントローラーに「about」アクションを手動で追加しようとしています。私たちは TDD を実践しているので、最初に失敗するテストを書いています。ただし、出力されるエラーメッセージが非常に長いため(これが標準かどうかはわかりません)、出力を短くする方法があるかどうか知りたいです。前もって感謝します!

test/controllers/static_pages_controller_test.rb: 次のコードを作成します (簡潔にするために、以前の 2 つの合格したテストは省略されています)。

require "test_helper"

class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  test "should get about" do
    get static_pages_about_url
    assert_response :success
  end
end

次に、ターミナルで次のコマンドを実行してテストを実行します。

% rails test

予想どおり、端末への出力には 1 つのエラーが表示されます。ただし、エラーは非常に長く (VS Code ターミナルに収まらないほど長いため、システム ターミナルで表示する必要があります)、問題のエラーの始まりを確認するには数百行を上にスクロールする必要があります。

エラーのサンプル:

Minitest::UnexpectedError: NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x00007fefbd442320 @_routes=nil, @NAME="test_should_get_about", @failures=[#<Minitest::UnexpectedError: Unexpected exception>], @assertions=0, @integration_session=#<#<Class:0x00007fefbd441c40>:0x00007fefbd4414c0 @_routes=nil, @app=#<SampleApp::Application:0x00007fefbd2fc308 @_all_autoload_paths=["/Users/christophermarchant/Documents/odin-project/full-stack-ruby/rails-course/hartl_rails_tutorial/sample_app/environment/sample_app/app/channels", "/Users/christophermarchant/Documents/odin-project/full-stack-ruby/rails-course/hartl_rails_tutorial/sample_app/environment/sample_app/app/controllers", ... @stubs=#<Concurrent::Map:0x00007fefbcd08550 entries=0 default_proc=#<Proc:0x00007fefbcd084b0 /Users/christophermarchant/.rbenv/versions/3.0.3/lib/ruby/gems/3.0.0/gems/activesupport-6.1.5/lib/active_support/testing/time_helpers.rb:14>>>, @time=0.12419799994677305>

エラー全体はさらに長くなります。

Rails は、StaticPagesControllerTest オブジェクト全体をそのすべての属性とともに検査して出力しているようです。

主な質問: 次のように、NameError が短くなるように構成を変更する方法はありますか?

NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x00007fefbd442320>

他の情報

Gemfile:

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.3'
gem 'rails', '~> 6.1.5'
gem 'puma', '~> 5.0'
gem 'sass-rails', '>= 6'
gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'

gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  gem 'sqlite3', '~> 1.4'
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console', '>= 4.1.0'
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  gem 'spring'
end

group :test do
  gem 'capybara', '>= 3.26'
  gem 'selenium-webdriver', '>= 4.0.0.rc1'
  gem 'webdrivers', '~> 5.0'
  gem 'rails-controller-testing', '~> 1.0', '>= 1.0.5'
  gem 'minitest', '~> 5.15'
  gem 'minitest-reporters', '~> 1.5'
  gem 'guard', '~> 2.18'
  gem 'guard-minitest', '~> 2.4', '>= 2.4.6'
end

group :production do
  gem 'pg', '~> 1.3', '>= 1.3.4'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

test/test_helper.rb ファイル:

ENV['RAILS_ENV'] ||= 'test'
require_relative "../config/environment"
require "rails/test_help"
require "minitest/reporters"

class ActiveSupport::TestCase
  # Run tests in parallel with specified workers
  parallelize(workers: :number_of_processors)

  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
end

Minitest::Reporters.use!(
  Minitest::Reporters::SpecReporter.new(:color => true),
  ENV,
  Minitest.backtrace_filter
)

システムとバージョン:

Ruby on Rails 6.1.5

ルビー 3.0.3p157

macOS Big Sur バージョン 11.6.4

解決策

ブルートフォースアプローチを採用して Minitest::Test#sanitize_Exception を書き直すと、機能するようです。これを行わないと、文字通り 20,000 行のメッセージ/バックトレースが表示され、UnexpectedError の先頭までスクロールすることになります。

# place this module in your `test_helper.rb` 

class Minitest::Test
  include FactoryBot::Syntax::Methods
  include ActiveSupport::Testing::Assertions

  def sanitize_exception(e)
    new_exception e.class, e.message.truncate(2000, omission: '... (truncated from test_helper.rb sanitize_exception)'), e.backtrace.first(10)
  rescue
    super(e)
  end