Rspec view тестирование с капибарой и рельсами3

Мне действительно нравится способ, которым RSpec может разделять контроллеры и тесты просмотра, но у меня есть некоторые проблемы с тем, чтобы заставить сопоставителей капибары работать в тесте представления. То, что я в основном пытаюсь достичь, это вот что:

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 или любого другого подходящего инструмента), что было бы также замечательно - использование капибары не является обязательным требованием,

7 ответов

Теперь есть возможность использовать средства сопоставления 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

Полный код:

Рекомендации:

Capybara в настоящее время не работает со спецификациями вида (есть планы сделать так, чтобы это работало в будущем). Самый простой ответ - просто добавить gem 'webrat' в Gemfile, и вы в основном настроены. Вы можете не иметь have_button но у тебя будет have_selector, have_tag и подобное доступно.

Кстати, насколько я знаю, капибара и вебрат могут сосуществовать в одном проекте.

Чуть проще, чем ответ Павла, но суть та же; следующие работы у меня с рельсами 3.1.0, rspec 2.6.0, капибара 1.1.1:

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

Вы не можете вызывать методы капибары на renderedэто просто строка. Вы можете использовать строковый метод Капибары, чтобы обернуть rendered в узле капибары. Затем вы можете вызвать методы 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

В нижней части этой страницы, в разделе "Вебрат и Капибара", похоже, что Капибара не поддерживается для спецификаций вида rspec

http://relishapp.com/rspec/rspec-rails

Обновление этого старого вопроса, поскольку все изменилось с тех пор, как было добавлено большинство других ответов:

Capybara теперь поддерживает спецификации вида (из коробки), и это описано в основной ветке 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) Код стиля, кажется, был добавлен в более ранней версии. (У меня это работает в капибарах 2.4.4 и 2.2).
Также обратите внимание, что поддерживается только ограниченное подмножество сопоставителей; однако вы можете получить больше функциональности, используя Capybara.string; например:

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

Вы также можете использовать синтаксис капибары

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
Другие вопросы по тегам