Rails Testing - Notes

Menu

Random notes about testing applications in Rails.

Fixtures

  • Fixtures can use ERB, no need to change file extension. Remember to index entries

    <% (1..10).each do |i| %>
    product_<%= i %>:
      name: Product <%= i %>
      managed_by: user_<%= i %>
    <% end %>
    
  • Fixtures can be generated from records, by putting the following code in initializers (source: ruby on rails - How to generate fixtures based on my development database? - Stack Overflow)

    # find me in initializers dump_fixtures.rb
    class ActiveRecord::Base
      def dump_fixture
        table_name = self.class.table_name
        fixture_file = "#{Rails.root}/test/fixtures/#{table_name}.yml"
        File.open(fixture_file, "a+") do |f|
          table_id = "#{table_name.singularize}_#{id}"
          f.puts({ table_id => attributes }.to_yaml.sub!(/---\s?/, "\n"))
        end
      end
    end
    

    and then:

    irb
    irb(main):001:0> User.first.dump_fixture
    

    Remember to fix references to other records (which will presumably be names of other fixtures, rather than ids).

Rails System Testing

Capybara runs under the hood.

Notice that you can debug test scripts. Require debug (or byebug) and insert breakpoints where needed. This is useful, for instance, to check selectors work.

Rails Testing Console

  • The console is available also for the testing environment. Remember that you need to manually load fixtures with:

    rails db:fixtures:load RAILS_ENV=testing
    

Delayed Jobs

Remember to start delayed jobs also for testing purposes or avoid the queue altogether in the configuration:

$ cat config/initializers/delayed_job.rb
if Rails.env.test?
  Delayed::Worker.delay_jobs = false
elsif Rails.env.development?
  Delayed::Worker.delay_jobs = false
else
  Delayed::Worker.delay_jobs = true
end

Start delayed job with:

$ ./bin/delayed_job:start

Clear queue:

$ rails c
irb> Delayed::Job.destroy_all

Testing Emails

Letter Opener

Letter opener generates a file in tmp/letter_opener for each email.

The launchy gems automatically opens email in browser. Don’t use it if the app sends many emails.

gem "launchy", group: :development
gem "letter_opener", group: :development
$ cat config/environments/development.rb
[...]
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.perform_deliveries = true

Letter Opener Web

Alternative to letter opener, Letter opener web generates a route to view emails sent by the app:

$ cat config/environments/development.rb
[...]
config.action_mailer.delivery_method = :letter_opener_web
[...]

In config/routes.rb:

if Rails.env.development?
  mount LetterOpenerWeb::Engine, at: "/inbox"
end