使用Capybara下载CSV

时间:2013-10-03 16:22:03

标签: ruby rspec capybara

对于rspec测试,我需要以CSV文件格式下载报告并验证所提供的信息。

单击按钮时,会从网页生成报告。浏览器保存对话框处于打开状态,提供打开或保存的选项。

如何使用rspec和Capybara将文件保存到计算机中?

3 个答案:

答案 0 :(得分:10)

我一直在使用MiniTest::Spec并使用webkit驱动程序,但它应该转换为RSpec没有问题,因为它基本上只是Capybara功能:

scenario "download overview" do
  within "aside#actions" do
    click_link "Download overview"
  end
  page.status_code.must_equal 200
  page.response_headers['Content-Type'].must_equal "text/csv"
  page.response_headers['Content-Disposition'].must_match /attachment; filename="Übersicht.*\.csv/
  page.must_have_content "Schubidu"
  page.must_have_content "U13"
  page.wont_have_content "5000"
end

我没有详细介绍数据的格式,但应该存在的记录和那些不应该被遗漏的记录(当然这只是一个小数据集来保持测试的快速性)。

答案 1 :(得分:6)

假设您的控制器操作看起来像这样:

require 'csv' # assuming you have this line somewhere

  def download
    @records = MyModel.all
    csv_data = CSV.generate do |data|
      data << ["Field 1", "Field 2"]
      @records.each do |record|
        data << [record.field1, record.field2]
      end
    end
    send_data csv_data, type: "text/csv", filename: "my_file.csv"
  end

我能够使用Capybara来验证单击我的按钮会导致浏览器触发下载提示:

click_on 'Download as CSV'
header = page.response_headers['Content-Disposition']
header.should match /^attachment/
header.should match /filename="my_file.csv"$/

请注意,page.response_headers是特定于驱动程序的。我正在使用capybara-webkit。 Content-Disposition标头应包含attachment而不是inline,因为它会导致下载提示。 Capybara还将文件的内容显示为响应主体(尽管这也可能是特定于驱动程序的),因此很容易验证输出:

MyModel.all.each do |record|
  page.should have_content record.field1
  page.should have_content record.field2
end

答案 2 :(得分:2)

如果您“验证所提供的信息”,那么您使用DMKE的第二个答案。您可能需要先发布到登录表单以获取会话cookie,然后使用post而不是获取将导致文件下载的表单。

如果结果使用javascript和iframe下载文件,则解析返回的html,提取实际网址以下载信息并从中下载数据。

我个人的偏好是根据检查到源代码控制中的文件副本来测试我的代码,因此我自己的代码的测试不依赖于外部站点的启动和可用。我编写了一个rake任务/帮助程序类,以便根据需要获取数据的新副本,并进行一些简单的测试以验证我可以将数据文件解码为有意义的内容。

如果测试确切地验证了数据的解码方式,那么您将需要一个固定的输入文件。如果您只是验证它“看起来合理”,那么您可以