rspec/rspec-rails

Auto-compile assets when running with `rspec`

mockdeep opened this issue · 9 comments

Is your feature request related to a problem? Please describe.

When using jsbundling-rails, assets are not precompiled automatically when running tests via the rspec command line:

$ rspec spec/path/to/my_spec.rb

But they are when run via the rake task:

$ SPEC=spec/path/to/my_spec.rb rake spec

Describe the solution you'd like

I would love it if behavior across these was consistent. I prefer to use the rspec command since it allows me to easily pass options to rspec, such as --fail-fast or specific filters.

Describe alternatives you've considered

For now we're considering adding yarn build to our rails_helper.rb so that it builds at the beginning of each test run.

pirj commented

Hey @mockdeep !

Indeed those two should run similarly.
jsbundling-rails does this here.

Is my understanding correct precompiling assets are only needed for feature and system specs?
Would it make sense to precompile in other cases?
I've seen projects where precompilation is quite slow and non-incremental. Doing a minutes-long full precompilation before each run of a single model spec would be annoying.
Wondering how this works in Minitest world.

@pirj I'm not sure, but we might need it in controller tests as well in order to properly render the include tags in the html. I'm not familiar with how sprockets or webpacker handle it, but they seem to work out of the box. In my very limited experience with esbuild, it is orders of magnitude faster. From a clean slate it takes less than a second to compile a 1.5mb JS package.

pirj commented

Right, I can't recall any similar issues with sprockets.
What concerns me is that jsbundling-rails has support for Webpack, and some may stick with this setup for a while.

rspec-rails is a thin wrapper around Rails own test helpers, thus it should behave consistently as Rails would (but not necessairly rake), the only tests this would affect in Rails are system tests, controller tests were replaced by request tests, but neither render assets, only link to them

main Rails currently decides when to compile assets depending on the way one is calling rails test.

rails test specific_test.rb => does not compile assets
rails test => does compile assets

See this line for the exact condition. This comment summarizes the behavior and the idea behind it.

Currently calling rspec does not compile assets, since it is currently not connected to the test:prepare or spec:prepare task (see here why hooking into the test/spec:prepare task builds asset at all when using the js-bundling gem). Calling rake spec hooks into the prepare task and therefore compiles assets.

I looked into fixing this in rspec-rails, but I'm not sure if we're able to implement a similar logic here without changing the rspec-core runner. If anyone could give me a hint how to go about it in rspec-rails I'd be more than happy to help fix this issue :)

RSpec probably also has some more edge-cases than minitest, e.g. when running focused specs, where the command in the terminal would look the same but maybe? the asset compile behavior should change? I'm not even sure myself what I would expect in this case :)

If its a case of calling the right rake task, then the command is rake spec and it should all work if the dependencies are setup correctly, if that doesn't work we need to fix that but thats why we have a custom rake task, otherwise I guess the thing to do would be look for the hooks that those tasks call in rails and call them in suite hooks

tonekk commented

As I wrote here, executing rake assets:precompile from "within" rspec (i.e. when rspec has already booted up) seems to be insufficient.
It seems like the rspec env is then using the old versions of the assets.
Does anyone know more about this?

Do you have a simple repo with a reproduction for your behavior? I've not seen such a behavior before, but would be interested.

I hit this problem with a new project. Here it is. If you run rspec spec it fails. If you run rake spec it passes.

rake assets:precompile before running rspec spec also works. When "resetting" for testing, I am removing the app/assets/builds folder.