简体   繁体   English

在Rails4 / Capybara / Rspec3中测试sidekiq WebUI可达性

[英]Testing sidekiq WebUI reachability in Rails4/Capybara/Rspec3

I'm currently moving some feature tests from Minitest to RSpec. 我目前正在将一些功能测试从Minitest移至RSpec。 My last problem is with reaching the Sidekiq WebUI which I enabled in my routes.rb 我的最后一个问题是到达我在routes.rb启用的Sidekiq WebUI

require 'sidekiq/web'
require 'admin_constraint'

Rails.application.routes.draw do
  mount Sidekiq::Web => '/sidekiq', constraints: AdminConstraint.new
  ...
end

The ressource is admin-only protected, which I now want to test. 资源受管理员保护,我现在要测试。 I have two questions 我有两个问题

1) Contemplating about the test again made me think, whether it would be better formulated as a routing test. 1)再次考虑该测试使我开始思考,是否可以将其更好地表述为路由测试。 What do you think? 你怎么看? Keep in mind that it routes to an external Engine which might make it kinda more complicated. 请记住,它路由到外部引擎,这可能会使它更加复杂。 The feature test seemed an easy way around this (simply test whether the ressource is reachable). 功能测试似乎是解决此问题的简便方法(只需测试资源是否可访问)。

2) In Minitest I could do eg the following, which was working fine 2)在Minitest中,我可以执行以下操作,但效果很好

require_relative '../test_helper'

feature 'Sidekiq dashboard' do
  scenario 'Dashboard cannot be reached as guest user' do
    assert_raise ActionController::RoutingError do
      visit sidekiq_web_path
    end
  end

  scenario 'Dashboard cannot be reached as regular user' do
    login_as_user

    assert_raise ActionController::RoutingError do
      visit sidekiq_web_path
    end
  end

  scenario 'Dashboard can be reached as admin' do
    login_as_admin
    assert_nothing_raised do
      visit sidekiq_web_path
    end
  end
end

I tried to convert it to RSpec directly like so 我试图像这样直接将其转换为RSpec

scenario 'Dashboard can be reached as user' do
  login_as_user

  expect {
    visit sidekiq_web_path
  }.to raise_error(ActionController::RoutingError)
end

which produces the following error 产生以下错误

Failures:

  1) Sidekiq dashboard Dashboard cannot be reached as regular user
     Got 1 failure and 1 other error:

     1.1) Failure/Error:
            expect {
              visit sidekiq_web_path
            }.to raise_error(ActionController::RoutingError)

            expected ActionController::RoutingError but nothing was raised
          # ./spec/features/sidekiq_monitoring_spec.rb:12:in `block (2 levels) in <top (required)>'

     1.2) Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"

          ActionController::RoutingError:
            No route matches [GET] "/sidekiq"
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/rack/logger.rb:38:in `call_app'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/rack/logger.rb:20:in `block in call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/rack/logger.rb:20:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/request_store-1.3.2/lib/request_store/middleware.rb:9:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/methodoverride.rb:22:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/runtime.rb:18:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/lock.rb:17:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/sendfile.rb:113:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/engine.rb:518:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/railties-4.2.7.1/lib/rails/application.rb:165:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/urlmap.rb:66:in `block in call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/urlmap.rb:50:in `each'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/urlmap.rb:50:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/capybara-2.12.0/lib/capybara/server.rb:43:in `call'
          # /home/blubber/.rvm/gems/ruby-2.3.1/gems/rack-1.6.5/lib/rack/handler/webrick.rb:88:in `service'
          # ------------------
          # --- Caused by: ---
          # Capybara::CapybaraError:
          #   Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true
          #   /home/blubber/.rvm/gems/ruby-2.3.1/gems/capybara-2.12.0/lib/capybara/session.rb:129:in `raise_server_error!'

Why does this not work in RSpec? 为什么这在RSpec中不起作用?

Thanks in advance, all the best, Andi 在此先感谢您,Andi

When testing with a JS capable driver (poltergeist, etc) Capybara runs the app in a separate server thread. 使用支持JS的驱动程序(poltergeist等)进行测试时,Capybara在单独的服务器线程中运行该应用程序。 Because of that errors raised in the app don't automatically get seen in the test code. 因此,应用程序中引发的错误不会自动出现在测试代码中。 To overcome that Capybara stores any errors raised in the server and, due to the asynchronous nature of commands when using a JS capable driver, re-raises them in the test code the next time it attempts to interact with Capybara. 为了克服该问题,Capybara将所有引发的错误存储在服务器中,并且由于使用支持JS的驱动程序时命令的异步特性,因此下次尝试与Capybara进行交互时会在测试代码中重新引发它们。 Because of that you would need to have a second interaction inside the block you expect to raise the error 因此,您需要在块内进行第二次交互,以期望引起错误

expect {
  visit sidekiq_web_path
  expect(page).to have_text("Something")  # the error will actually raise here
}.to raise_error(ActionController::RoutingError)

I have no clue why it was working for you like that with minitest, and would have to go look at the Minitest code to attempt to figure out why. 我不知道为什么它以minitest的方式为您工作,并且不得不去看看Minitest的代码以试图找出原因。 I would expect your tests to have worked correctly if you were running those tests with the rack_test driver since it doesn't run a separate thread and just calls directly into the app (you claim not to have changed that though). 如果您使用rack_test驱动程序运行那些测试,我希望您的测试能够正常工作,因为它没有运行单独的线程,而只是直接调用应用程序(尽管您声称并没有改变)。

Note: This really isn't the sort of thing that you should be checking in a feature test, instead it would be better to check for what is displayed on the page when permission is denied/allowed instead of a specific error class that is raised 注意:这实际上不是您应该在功能测试中检查的事情,而是最好在拒绝/允许权限时检查页面上显示的内容,而不是引发特定的错误类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM