<Marc Qualie/>

Testing Rails 6 Zeitwerk Autoloading

Rails 6 introduced a new autoloader called Zeitwerk. While it has many many improvements, one of the main changes is how strict it is with filenames and the constants they define. Unless you have full coverage on your application (few apps actually reach 100%) it can be quite easy to end up with an app that won't boot in your staging/production environment.

This is a welcome change from me, I believe it leads to much more stable and predictable codebases when the filenames and constants match 1:1. This can become an issue for anyone used to working with the rails classic autoloader since that allowed developers to get away with mostly anything inside their files.

Adding the following spec to any new rails 6+ project will protect from such problems, as the autoloading will be triggered in the CI environment instead; before merge and deploy. This is also perfect if you're upgrading any older Rails 5 apps and you're nervous about switching to the new autoloader.

# spec/zeitwerk_spec.rb
require 'rails_helper'

describe 'Zeitwerk' do
  it 'eager loads all files' do
    expect do
      Zeitwerk::Loader.eager_load_all
    end.to_not raise_error
  end
end

Original reference post for code snippet Rails 6 and Rspec : How to test Zeitwerk mode by Matthieu Varagnat

You can take this a step further on CI and have a dedicated job that runs specifically to check the autoloading. This can be dne before the tests (to avoid wasted minutes), or in parallel to highlight an autoloading issues in your PR status checks.

The following line can run in any shell to perform the same job as the rspec snippet above:

rails r 'Zeitwerk::Loader.eager_load_all'

Here is an example of my CircleCI flow for a recently upgraded rails project. Notice how Zeitwerk failure prevented a ton of other jobs triggering, which would have used quite a lot of resources and failed much later.

Screen-Shot-2021-01-20-14-02-56.26.png

Screen-Shot-2021-01-20-14-05-09.95.png

This, of course, does not replace the need for an extensive test suite, but it can save you in the early days of prototype development where a typo or unused class can slip into the codebase when working at a fast pace.

If you have any questions about this post, or anything else, you can get in touch on Bluesky or browse my code on Github.