Skip to content

Halve the time it takes to run view specs by enabling the resolver cache #1452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 20, 2015

Conversation

zetter
Copy link
Contributor

@zetter zetter commented Sep 2, 2015

Hi,

Recently at FutureLearn we have taken some time to try and speed up our tests.

We have lots of view specs in our test suite, and we noticed that they took quite a while to run. This surprised us given that one of the benefits of testing views independently is speed. We found that one of the reasons for this slowness was that rspec-rails had disabled the ActionView resolver cache, increasing the time it took to load views.

There are two commits in this pull request. The first contains a fix the original issue which caused the cache to be disabled, the second enables the cache again. Please see their respective commit messages for more detail. When running our tests against this branch, it halves the time it takes us to run our view specs.

I'd like to hear peoples thoughts on this change, particularly:

  • Could converting the format to a symbol introduce breaking changes for anyone? The FutureLearn and rspec-rails test suites are fine, but I don't know if people are testing views in other ways.
  • Are there any other reasons why a user of rspec-rails might want ActionView's resolver cache to be disabled?

Rails expects value of the `:format` option be a symbol. It filters
formats against `Mime::SET.symbols` so formats which are unknown
(or are known but are of an unexpected type) are not used in cache keys
for the Rails' `ActionView::Resolver::Cache`. This made the resolver
cache unusable when there was multiple templates with the same name but
different formats and was the reason the cache was disabled in
rspec-rails [1].

This isn't the only way of fixing this problem- for example Rails could
be changed to ensure symbols aren't compared with strings as was
suggested in [2], but I feel that it's rspec-rails' responsibility
to work with the existing Rails API.

[1] rspec#864
[2] rails/rails#13461
The caching was turned off in [1] because different formats were being
cached under the same key. I believe the need to do this was removed
in the previous commit.

This reduces the time it takes to run FutureLearn’s view specs by 50%.

I think it’s sensible to use the view resolver cache during tests because
it’s normally on between requests in other environments including when
creating tests with `ActionView::TestCase` in a new Rails application.
It looks like it was only turned off in rspec-rails to work around this
caching issue.

I haven't added any test coverage in this change since it feels like
it would be testing a negative (the resolver cache isn't cleared).

[1] rspec#864
@JonRowe
Copy link
Member

JonRowe commented Sep 2, 2015

Could converting the format to a symbol introduce breaking changes for anyone?

Vaguely, this rings a bell, I believe the reason why we didn't just do this at the time is rails treats views with strings and symbols differently

@zetter
Copy link
Contributor Author

zetter commented Sep 3, 2015

@JonRowe thanks for taking a look at this,

I believe the reason why we didn't just do this at the time is rails treats views with strings and symbols differently

I couldn't see any reference to this in the original commit or subsequent discussion that suggests that there would be a problem marking the value of format a symbol. Can anyone provide an example of existing test that would behave unexpectedly after this change?

I have looked myself and could only think of an issue when a user of rspec-rails has registered multiple custom mime types with a string rather than a symbol, e.g:

Mime::Type.register "audio/mp3", "mp3"
Mime::Type.register "audio/mp4", "mp4"

This change would cause the resolver cache to mix templates during tests in this case. It looks to me from the Mime::Type.register API that the second argument is expected be a symbol (based upon examples and the parameter name) so I don't think we should worry about this case. This change also continues allow the options to render to be overridden and a stringified format to be provided if needed.

@JonRowe
Copy link
Member

JonRowe commented Sep 8, 2015

/cc @cupakromer

@soulcutter
Copy link
Member

Seems like this originated from 96d3e75 - if the cukes are passing now perhaps it's no longer necessary? Would this break view specs for people using some outdated version of rails that has the invalidation issue that @JonRowe referenced?

I don't know… but if they're upgrading their RSpec and staying on a legacy version of rails I think that they should probably use an older rspec-rails until they update their rails since it sounds like more of a bug on rails' side.

So I think I've talked myself into 👍 :shipit: on this issue.

soulcutter added a commit that referenced this pull request Sep 20, 2015
Halve the time it takes to run view specs by enabling the resolver cache
@soulcutter soulcutter merged commit af78962 into rspec:master Sep 20, 2015
soulcutter added a commit that referenced this pull request Sep 20, 2015
@zetter
Copy link
Contributor Author

zetter commented Sep 21, 2015

@soulcutter thanks for your time spent reviewing this and merging it in.

In case anyone else has a lot of view specs and wants to take advantage of this change now (but doesn't want the other changes on master or to use the pre-release rspec gems) I have back-ported these commits to 3.3.3 at https://github.com/Futurelearn/rspec-rails/tree/faster-view-specs-backport

You can use this by changing the rspec-rails gem in your Gemfile to use this fork, e.g:

gem 'rspec-rails', git: 'https://github.com/Futurelearn/rspec-rails.git', branch: 'faster-view-specs-backport'

sebjacobs pushed a commit to futurelearn/rspec-rails that referenced this pull request Mar 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants