【问题标题】:Testing multidomain Rails 3 app with Capybara使用 Capybara 测试多域 Rails 3 应用程序
【发布时间】:2011-01-18 12:29:24
【问题描述】:

我想测试我的多域 RoR3 应用程序。

这是我的 test_helper.rb

ENV["RAILS_ENV"] = "test"

require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'capybara/rails'
require 'blueprints'

class ActiveSupport::TestCase

end

class ActionDispatch::IntegrationTest
  include Capybara

  def host
    "http://#{subdomain}.lvh.me:3000"
  end

  def subdomain
    @subdomain ? @subdomain : 'demostore'
  end

  def visit(url)
    super("http://#{subdomain}.lvh.me:3000#{url}")
  end
end

还有我的集成测试:

require 'test_helper'

class ProductsTest < ActionDispatch::IntegrationTest

  def setup
    @subdomain = 'demostore'
    # creating stuff
  end

  def teardown
    # deleting stuff
  end

  test "user views product list" do
    visit('/')
    assert page.has_css?('ul.product-listing')
    assert page.has_xpath?("//ul[@class='product-listing']/li", :count => 12)
  end

  test "user views product page" do
    product = Product.first

    visit('/')
    find(:xpath, "//ul[@class='product-listing']/li/a[1]").click
    save_and_open_page
  end

end

我确定链接存在。点击和填充内容有问题。

click_link('Existent link title')

也不行。

我认为默认 Capybara 的驱动程序 Rack::Test 可能对这个多域的东西有问题?

【问题讨论】:

  • 您能分享您的解决方案吗?你把端口设置成什么了?谢谢!夏兰
  • 是的,我也想看看解决方案。

标签: ruby-on-rails integration-testing capybara


【解决方案1】:

在您的设置中,调用 rack::test 函数,这将更改您主机的值。好吧,它会更改返回的有关虚假 Web 请求的主机。

host! "#{store.subdomain}.example.com"

【讨论】:

  • 这行不通。我已经通过在 Capybara 的设置中设置主机和端口来解决它。
【解决方案2】:

问题是我正在使用多域的东西,所以我不得不使用解析本地主机的 lvh.me。你可以通过设置你的 /etc/hosts 来做同样的想法

127.0.0.1 subdomain.yourapp.local

然后使用这个域。

我已经用这样的方式覆盖了 Capybara 的访问方法:

def visit(link)
  super("mysubdomain.lvh.me:3000#{link}")
end

但问题仍然存在,因为当 Capybara 单击示例链接时,未使用访问方法并且未请求我的主机。哪个是?我不知道 - 可能是默认的。

所以解决方法是在Capybara设置中设置主机和端口:

class ActionDispatch::IntegrationTest
  include Capybara

  Capybara.default_host = "subdomain.yourapp.local"
  Capybara.server_port = 3000
  # ... rest of stuff here
end

【讨论】:

  • 我在设置Cabybara.default_host 时遇到的问题是它为所有规格全局设置了它。这导致我以前的一些规格被打破。 “Capybara 的作者 Jonas Nicklas,states'永远不要更改 Capybara.default_host,只是不要。'并建议显式访问子域。” (来自minimul.com/capybara-and-subdomains.html
  • 在上面的评论中同意 Christian 的解决方案。这才是真正的答案。谢谢
【解决方案3】:

显然这是机架测试的问题。

但是hassox 的一个分支刚刚为我解决了这个问题。 这只是几个真正重要的提交,以防您想检查更改是什么。

这就是我的 Gemfile 的外观:

group :test, :cucumber do
  gem 'rack-test', :git => "https://github.com/hassox/rack-test.git"
  gem 'capybara', '= 0.4.1.2'
  gem 'capybara-envjs', '= 0.4.0'
  gem 'cucumber-rails', '>= 0.3.2'
  gem 'pickle', '>= 0.3.4'
end

然后我只是确保

visit('http://my_subdomain.example.com')

在我的步骤中。现在我正在尝试了解什么会使 url 帮助程序与子域一起使用。

【讨论】:

    【解决方案4】:

    这里有一个快速设置可以帮助你...

    rails 3.2+ 使用带有 pow 设置的黄瓜水豚测试自定义子域:

    https://gist.github.com/4465773

    【讨论】:

      【解决方案5】:

      我想分享我发现的解决此问题的好方法。它涉及创建一个辅助方法以在 URL 前添加所需的子域,不覆盖任何 Capybara 方法,并与 Rack::Test 和 capybara-webkit 驱动程序一起使用。事实上,它甚至可以在甚至不使用 Capybara 的规格中工作。 (来源:http://minimul.com/capybara-and-subdomains.html

      规范助手方法

      # spec/support/misc.helpers.rb
      def hosted_domain(options = {})
        path = options[:path] || "/" # use root path by default
        subdomain = options[:subdomain] || 'www'
        if example.metadata[:js]
          port = Capybara.current_session.driver.server_port
          url = "http://#{ subdomain }.lvh.me:#{ port }#{ path }"
        else
          url = "http://#{ subdomain }.example.com#{ path }"
        end
      end
      


      为了说明它的用途,这里有两个例子:

      在功能规范中使用(与 Ca​​pybara 一起)

      require 'spec_helper'
      
      describe "Accounts" do
        # Creates an account using a factory which sequences
        # account subdomain names
        # Additionally creates users associated with the account
        # using FactoryGirl's after callbacks (see FactoryGir docs)
        let (:account) { FactoryGirl.create(:account_with_users) })
      
        it "allows users to sign in" do
          visit hosted_domain(path: new_sessions_path, subdomain: account.subdomain)
      
          user = account.users.first
      
          fill_in "email", with: user.email
          fill_in "password", with: user.password
          click_button "commit"
      
          # ... the rest of your specs
        end
      end
      

      在请求规范中使用(没有 Capybara)

      #spec/requests/account_management_spec.rb
      require "spec_helper"
      
      describe "Account management" do
        # creates an account using a factory which sequences
        # account subdomain names
        let (:account) { FactoryGirl.create(:account) })
      
        it "shows the login page" do
          get hosted_domain(path: "/login", subdomain: account.subdomain)
          expect(response).to render_template("sessions/new")
        end
      
      end
      

      【讨论】:

        【解决方案6】:

        一个简单而干净的解决方案是覆盖您提供给 Capybara 访问方法的 url。它适用于 *.lvh.me 域,它将您重定向到 localhost:

        describe "Something" do
        
          def with_subdomain(link)
            "http://subdomain.lvh.me:3000#{link}"
          end
        
          it "should do something" do
            visit with_subdomain(some_path)
          end
        
        end
        

        或者您可以通过在规范之前重新定义 app_host 来做同样的事情:

        Capybara.app_host = 'http://sudbomain.lvh.me:3000'
        ..
        visit(some_path)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-13
          • 2018-06-06
          • 1970-01-01
          • 2012-10-21
          相关资源
          最近更新 更多