Rails: Testing file downloads with request specs

Posted . Visible to the public. Repeats.

tl;dr

Prefer request specs over end-to-end tests (Capybara) to joyfully test file downloads!

Why?

Testing file downloads via Capybara is not easy and results in slow and fragile tests. We tried different approaches and the best one is just okay.

Tests for file downloads via Capybara ...

  • ... are slow,
  • ... are fragile (breaks CI, breaks if Selenium driver changes, ...),
  • ... need workarounds for your special use cases,
  • ... and have limitations.

How?

You should instead write request specs, because they ...

  • ... are fast,
  • ... are easy to write,
  • ... are stable,
  • ... and don't need workarounds.
describe Backend::ResourcesController do
  describe '#index' do
    it 'sends a xlsx export' do
      # create your exportable data

      create(:resource, ...)

      # call your export endpoint

      get '/backend/resources.xlsx'

      # check that all expectations are fulfilled

      expect(response).to be_ok
      expect(response.headers['Content-Disposition']).to eq('attachment; filename="export.xlsx"')
      expect(response.content_type).to eq('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
      expect(RubyXL::Parser.parse_buffer(response.body)).to contain_all_expected_data
    end
  end
end

But!

Using a request spec doesn't test my export link or button!

Then write a small end-to-end test, e.g. that only checks that your link has the correct href or that your link or button sends a request to the export endpoint.

How to test file downloads with Capybara

If you still want to write an end-to-end test with Capybara you should check out these cards:

Julian
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Julian to makandra dev (2024-03-15 12:37)