使用Capybara和Rails3进行Rspec视图测试

20

我非常喜欢 RSpec 能够分离控制器和视图测试的方式,但在进行视图测试时遇到了一些使用 capybara 匹配器的问题。基本上,我想要实现的是这样的:

describe "some page" do
  it "should render with lots of stuff" do
    assign ..
    render
    rendered.should have_button ('Any button') #or any capybara matcher, really
  end
end

我在网上看到一些帖子展示了如何配置capybara和rails3以与cucumber或rspec控制器测试平稳地工作,但这不是我真正想要的——也就是说,在尽可能低的级别上测试视图。

此外,如果有其他方法可以做到这一点(不需要大量自定义代码,因为我知道我可以编写一些匹配器从使用nokogiri或其他适合工具呈现的给定选择器中提取),那就太好了——使用capybara并不是必需的。

7个回答

18

现在测试控制器(以及视图)可以使用Capybara匹配器(不需要Webrat包)了。我是这样使用的:

describe GlobalizeTranslationsController do

  render_views
  let(:page) { Capybara::Node::Simple.new(@response.body) }

  describe "PUT :update" do
    before do
      put :update
    end

    it "displays a flash notice" do
      page.should have_selector('p.notice')
    end

  end

end

完整的代码:

参考资料:


1
我真的不建议像那样测试控制器。使用你的例子,那种类型的测试更适合在视图层级上进行。 - Nicholas Pufal
1
完全同意!控制器规范应该只测试控制器逻辑,而不是视图。如果您想测试视图,请创建请求/功能规范(使用Capybara + Poltergeist或capybara-webkit)。 - Paweł Gościcki
这是使用View Specs的完美案例:https://www.relishapp.com/rspec/rspec-rails/v/2-0/docs/view-specs/view-spec - rpearce

11

Capybara目前无法与视图规范(View Specs)一起使用(未来有计划使其能够工作)。最简单的解决方法就是在Gemfile中添加gem 'webrat',然后基本上就设置好了。你可能没有have_button,但你有have_selectorhave_tag和类似的可用。

顺便说一下:据我所知,Capyabara和Webrat可以共存于一个项目中。


有人在使用 Capybara 匹配器时遇到泄漏到视图测试中的问题吗? - Paulo Casaretto
对于那些最近路过的人,备注一下:Capybara现在支持视图规范了:https://github.com/jnicklas/capybara/blob/master/README.md#using-capybara-with-rspec - tgf

10

比Pawel的答案稍微简单,但要点是一样的;以下内容适用于我使用的rails 3.1.0,rspec 2.6.0,capybara 1.1.1:

page = Capybara::Node::Simple.new( rendered )
page.should have_content( "blah" )

4
你不能在字符串 rendered 上调用 capybara 的方法,它只是一个字符串。但是,你可以使用 Capybara.string 方法将 rendered 包装在一个 Capybara 节点中。然后,你可以在该节点上调用 Capybara 的方法:
describe "some page" do
  it "should render with lots of stuff" do
    assign ..
    render
    Capybara.string(rendered).should have_button('Any button')
  end
end

更多信息请查看以下文章:

http://www.tamingthemindmonkey.com/2011/11/07/capybara-matchers-and-scoping-in-view-specs

这篇文章是关于使用Capybara Matchers和Scoping的视图规范的。

1

由于其他答案被添加以来,情况已经发生变化,现在更新这个旧问题:

Capybara 现在支持视图规范(view specs) (开箱即用),并且这在 Capybara 的主分支上有记录。

引用文档:

最后,Capybara 匹配器在视图规范中得到了支持:

RSpec.describe "todos/show.html.erb", type: :view do
  it "displays the todo title" do
    assign :todo, Todo.new(title: "Buy milk")

    render

    expect(rendered).to have_css("header h1", text: "Buy milk")
  end
end

似乎在早期版本中已经添加了对这些没有额外let(:page)样式代码的支持。(在我的capybara 2.4.4和2.2中可以工作)
还要注意,仅支持有限的匹配器子集;但是您可以通过使用Capybara.string来获得更多功能;例如:

expect(Capybara.string(rendered).first('td')).to have_no_content 'Tom Riddle'

1

1
如果您使用Capybara的默认驱动程序(:rack_test),使用Capybara编写"请求测试"作为视图测试仍然可以获得相当不错的性能。这就是我实际上测试我的视图的方式。您只是不能使用assign,所以与"真正的"视图测试相比,您的控制力少了一点。 - Jo Liss

0

你也可以使用 capybara 语法

describe "some page" do 
  it 'should render hello with name' do
    assign(:user, double("User", first_name: "John"))
    render
    expect(rendered).to have_content("Hello John")
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接