使用Capybara测试多域Rails 3应用程序

时间:2011-01-18 12:29:24

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

我想测试我的多域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可能会遇到这个多域名的问题?

6 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

问题是我使用的是多域名,所以我不得不使用lvh.me来解析localhost。您可以通过在/ 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

答案 2 :(得分:1)

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

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助手与子域一起工作。

答案 3 :(得分:1)

这是一个可以帮助你的快速设置...

rails 3.2+使用黄瓜水豚与粉末设置测试自定义子域名:

https://gist.github.com/4465773

答案 4 :(得分:1)

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

Spec Helper方法

# 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

<小时/>

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

用于特征规范(与Capybara)

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

答案 5 :(得分:0)

一个简单而干净的解决方案是覆盖您为Capybara的访问方法提供的网址。它适用于* .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)