Ruby on Rails 6 with Minitest:有没有办法缩短输出错误?

问题描述 投票:0回答:1

我正在阅读 Michael Hartl 的 Ruby on Rails 教程 的第 3.3 节,我们刚刚开始测试部分。在本节中,我们将在控制器 (StaticPagesController) 中对静态页面进行分组,并尝试手动向控制器添加“关于”操作。因为我们正在练习 TDD,所以我们首先编写一个失败的测试。但是,输出的错误消息非常长(我不知道这是否是标准的),我想知道是否有办法缩短输出。预先感谢!

test/controllers/static_pages_controller_test.rb:我们编写以下代码(为简洁起见,省略了之前的两个通过测试):

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_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

ruby-on-rails ruby ruby-on-rails-6 minitest
1个回答
0
投票

采取蛮力方法并重写

Minitest::UnexpectedError
似乎有效。如果不这样做,我实际上会得到 20,000 行消息/回溯,滚动到顶部出现意外错误:

# place this module in your `test_helper.rb` 

module Minitest
  # copied from https://github.com/minitest/minitest/blob/ea9caafc0754b1d6236a490d59e624b53209734a/lib/minitest.rb#L841
  # goal is to truncate the extremely long error message...
  class UnexpectedError < Assertion
    attr_accessor :error # :nodoc:

    def initialize error # :nodoc:
      super "Unexpected exception"

      if SystemStackError === error then
        bt = error.backtrace
        new_bt = compress bt
        error = error.exception "#{bt.size} -> #{new_bt.size}"
        error.set_backtrace new_bt
      end

      self.error = error
    end

    def backtrace # :nodoc:
      self.error.backtrace
    end

    BASE_RE = %r%#{Dir.pwd}/% # :nodoc:

    def message # :nodoc:
      bt = Minitest.filter_backtrace(self.backtrace).join("\n    ")
        .gsub(BASE_RE, "")

      # truncate the message:
      truncated = "#{self.error.class}: #{self.error.message.truncate(2000, omission: '... (truncated from test_helper.rb Minitest::UnexpectedError)')}\n #{bt.first(10)}"

      # the original return value is here:
      # "#{self.error.class}: #{self.error.message}\n    #{bt}"
      # 
      truncated
    end

    def result_label # :nodoc:
      "Error"
    end
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.