RSpec before(:all) not behaving properly

1,923 views
Skip to first unread message

Mike Pack

unread,
Jun 11, 2011, 1:50:28 PM6/11/11
to vcr-...@googlegroups.com
When I use before(:each), VCR does exactly as it should but it's slow since it's making mock HTTP requests upon each RSpec example (are mock requests usually only about 33% faster than normal HTTP requests?) . So I want to use before(:all) but I get the following on the line that makes the HTTP request:

 WebMock::NetConnectNotAllowedError:
       Real HTTP connections are disabled. Unregistered request: GET http://...  You can use VCR to automatically record this request and replay it later.  For more details, visit the VCR documentation at: http://relishapp.com/myronmarston/vcr/v/1-10-0

Is this an issue with VCR or am I incorrectly trying to run a before(:all) block? Here is my code:

describe '#some_method' do
   use_vcr_cassette "my_cassette", :record => :new_episodes

   before(:all) do
    <MAKE HTTP REQUEST>
   end

   it 'does something' do
     ...
   end

   it 'does something else' do
     ...
   end
end

Myron Marston

unread,
Jun 11, 2011, 3:55:33 PM6/11/11
to vcr-...@googlegroups.com
> are mock requests usually only about 33% faster than normal HTTP requests?

It depends.  If the HTTP request is made to a super fast API (maybe it does a single constant-time lookup in a key-value datastore and returns the result), then you might not see much speedup.  If the HTTP request is made to a slow API, VCR will obviously make a much bigger difference.

When you cite the "33% faster" number, is that the improvement to your total test time from using VCR?  Or have you specifically benchmarked the parts of the test suite that make HTTP requests, with and without VCR?  A 33% improvement in total test time may actually indicate that the HTTP requests are multiple times faster, if the HTTP requests were only taking up 30% (or whatever) of your test time.

FWIW, FakeWeb is quite a bit faster than WebMock, but if only works with Net::HTTP.  I've got some benchmarks [1] if you're interested.

> Is this an issue with VCR or am I incorrectly trying to run a before(:all) block?

The issue is that you can't use the `use_vcr_cassette` macro with an HTTP request in a before(:all) block.  All `use_vcr_cassette` does is setup the appropriate before(:each) and after(:each) hooks [2].  RSpec runs the before(:all) hooks before it runs the before(:each) hooks for each example--so when your HTTP request is made in the before(:all) hook, the VCR cassette has not yet been inserted.  `use_vcr_cassette` is basically just a convenience macro for the 99% use case.  In your case, you can just use `VCR.use_cassette` (VCR's main API) directly in the before(:all) hook:

before(:all) do
  VCR.use_cassette("my_cassette", :record => :new_episodes) do
    # make http request
  end
end

Myron

Mike Pack

unread,
Jun 11, 2011, 7:01:03 PM6/11/11
to vcr-...@googlegroups.com
Myron, thanks for your answer. It was complete and helped me figure out what was going wrong.

As for the 33%, I took this number from the time it took to run 1 test which calls an API. My library actually makes 7 API calls within this one instance. The second run, with the data cached by VCR, was roughly 33% faster consistently. I tested this about 5 times. It's a very rough "benchmark" but I would love to see some official benchmarks done by the developers/community.

Thanks again Myron!

Mike

Mike Pack

unread,
Jun 11, 2011, 7:29:18 PM6/11/11
to vcr-...@googlegroups.com
Oops, sorry Myron, I missed your reference link to the benchmarks. Thanks again!


Mike

On 6/11/2011 1:55 PM, Myron Marston wrote:

et...@bigohstudios.com

unread,
Jan 11, 2013, 2:54:07 PM1/11/13
to vcr-...@googlegroups.com
You, sir, just saved hours of my life.  Thank you so much for posting this explanation!

guerin...@gmail.com

unread,
Jun 13, 2013, 5:40:02 PM6/13/13
to vcr-...@googlegroups.com
Super helpful knowledge, perhaps there is a better place to put this?
Reply all
Reply to author
Forward
0 new messages