Проверка просмотра Rspec с помощью capybara и rails3

Мне очень нравится, как 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 для бесперебойной работы с проверками контроллера огурца или rspec, но это не совсем то, что я хочу - то есть тестирование просмотров на самом низком уровне.

Также, если есть другой способ сделать это (не требуя большого количества настраиваемого кода, я знаю, что я мог бы написать некоторые матчи, которые извлекают данные селектора из рендеринга с помощью nokogiri или любого подходящего инструмента), что тоже было бы здорово - использование capybara не требуется.

Ответ 1

Теперь есть возможность использовать Capybara matchers (без багажа 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

Полный код:

Литература:

Ответ 2

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

Btw: насколько я знаю, capybara и webrat могут сосуществовать в одном проекте.

Ответ 3

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

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

Ответ 4

Вы не можете вызвать методы capybara на rendered, это просто строка. Вы можете использовать метод строки Capybara, но обернуть rendered в Capybara node. Затем вы можете вызвать методы Capybara на этом node:

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

Ответ 5

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

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

Ответ 6

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

Capybara теперь поддерживает спецификации вида (из коробки), и это описано на Capybara master branch.

Чтобы процитировать документы:

Наконец, помощники 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'

Ответ 7

Вы также можете использовать синтаксис 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