Skip to content

Commit

Permalink
Use before_all block to setup requests/cache_spec data
Browse files Browse the repository at this point in the history
This spec is looping through various collections of endpoints and
asserting different caching properties.

Previously, the `before` block here was running before every example,
and thus creating/dropping the full set of factories in every
example-wrapping transaction.

The change here is to use `before_all` which wraps the example group in
a big transaction and creates the factories (which, in this entire spec,
are very much like fixture data). The individual transactions around
each example from rspec are still in place, so for the few examples
which do modify any of the records, that will not pollute other specs.

Some before/after summary to show factory creation reduction:

BEFORE:
```
Finished in 23.1 seconds (files took 2.78 seconds to load)
253 examples, 0 failures

[TEST PROF INFO] Factories usage

 Total: 1611
 Total top-level: 1611
 Total time: 00:12.677 (out of 00:23.892)
 Total uniq factories: 6

   total   top-level     total time      time per call      top-level time               name

     506         506        2.6162s            0.0052s             2.6162s             status
     264         264        3.4650s            0.0131s             3.4650s            account
     253         253        3.5710s            0.0141s             3.5710s             invite
     253         253        0.4301s            0.0017s             0.4301s               poll
     253         253        2.4347s            0.0096s             2.4347s               user
      82          82        0.1603s            0.0020s             0.1603s accessible_access_token
```

AFTER:
```
Finished in 9.54 seconds (files took 2.72 seconds to load)
253 examples, 0 failures

[TEST PROF INFO] Factories usage

 Total: 18
 Total top-level: 18
 Total time: 00:00.860 (out of 00:10.325)
 Total uniq factories: 6

   total   top-level     total time      time per call      top-level time               name

      12          12        0.6972s            0.0581s             0.6972s            account
       2           2        0.0997s            0.0499s             0.0997s             status
       1           1        0.0093s            0.0093s             0.0093s               user
       1           1        0.0232s            0.0232s             0.0232s             invite
       1           1        0.0134s            0.0134s             0.0134s               poll
       1           1        0.0175s            0.0175s             0.0175s accessible_access_token
```

So, we are able to reduce:

- Total factory creation from ~1600 DB records to just under 20
- Percentage of time spent on factories from ~50% to under 10%
- Overall spec file run time by more than 50%
  • Loading branch information
mjankowski committed Mar 12, 2024
1 parent d4ed7e4 commit 4c90de6
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 11 deletions.
1 change: 1 addition & 0 deletions spec/rails_helper.rb
Expand Up @@ -21,6 +21,7 @@
require 'capybara/rspec'
require 'chewy/rspec'
require 'email_spec/rspec'
require 'test_prof/recipes/rspec/before_all'

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

Expand Down
22 changes: 11 additions & 11 deletions spec/requests/cache_spec.rb
Expand Up @@ -39,7 +39,7 @@ module TestEndpoints
/api/v1/accounts/lookup?acct=alice
/api/v1/statuses/110224538612341312
/api/v1/statuses/110224538612341312/context
/api/v1/polls/12345
/api/v1/polls/123456789
/api/v1/trends/statuses
/api/v1/directory
).freeze
Expand Down Expand Up @@ -166,14 +166,18 @@ module DisabledAnonymousAPI
ActionController::Base.allow_forgery_protection = old
end

let(:alice) { Fabricate(:account, username: 'alice') }
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Moderator')) }
let(:alice) { Account.find_by(username: 'alice') }
let(:user) { User.find_by(email: 'user@host.example') }
let(:token) { Doorkeeper::AccessToken.find_by(resource_owner_id: user.id) }

before do
status = Fabricate(:status, account: alice, id: '110224538612341312')
Fabricate(:status, account: alice, id: '110224538643211312', visibility: :private)
before_all do
alice = Fabricate(:account, username: 'alice')
user = Fabricate(:user, email: 'user@host.example', role: UserRole.find_by(name: 'Moderator'))
status = Fabricate(:status, account: alice, id: 110_224_538_612_341_312)
Fabricate(:status, account: alice, id: 110_224_538_643_211_312, visibility: :private)
Fabricate(:invite, code: 'abcdef')
Fabricate(:poll, status: status, account: alice, id: '12345')
Fabricate(:poll, status: status, account: alice, id: 123_456_789)
Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read')

user.account.follow!(alice)
end
Expand Down Expand Up @@ -321,8 +325,6 @@ module DisabledAnonymousAPI
end

context 'with an auth token' do
let!(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') }

TestEndpoints::ALWAYS_CACHED.each do |endpoint|
describe endpoint do
before do
Expand Down Expand Up @@ -585,8 +587,6 @@ module DisabledAnonymousAPI
end

context 'with an auth token' do
let!(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') }

TestEndpoints::ALWAYS_CACHED.each do |endpoint|
describe endpoint do
before do
Expand Down

0 comments on commit 4c90de6

Please sign in to comment.