#291 Testing with VCR pro
If you ever need to test an application which communicates with an external API, VCR is the way to go. Here I show a workflow in RSpec, how to use with capybara-mechanize, how to add sanitization filtering, and more.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
I was using VCR and come into a particular problem, i do no communicate to the web service directly i first establish a reverse ssh tunnel to another computer in the network, so i could not figure a way to capture the request. Any suggestions?
Since VCR only stubs HTTP requests it won't work over an SSH tunnel. However what you can do is setup a proxy server that is before the SSH tunnel and have VCR record requests that go to that server. I haven't actually tried this, and it's a bit advanced, but hopefully it will give you some ideas.
Can i use vcr with capybara + selenium?
Awesome episode. I add capybara-mechanize for OAuth testing in my app.
I don't think so, but I haven't tried it. VCR needs to stub out the HTTP request, so that needs to happen in Ruby. I don't think the Capybara Selenium driver uses Ruby at all to perform the HTTP requests. It instead communicates with Selenium at a higher level. I believe the same goes for Capybara Webkit and other alternatives.
That said, what you can do is setup a proxy Rack server which all remote requests go through. This can forward all HTTP requests to their remote destination using Net::HTTP and therefore use VCR to record it. It would look like this: Capybara > Selenium > Rack proxy server > Remote server.
To add to what Ryan said...it depends on what you mean. If you want to use VCR to record/replay HTTP requests made by your rack application, and you are using capybara + selenium to do full-stack integration testing--then yes. VCR isn't coupled to a particular capybara driver (or any testing library, really) so it should work fine, as long as you are making HTTP requests with one of the supported HTTP client libraries.
If you are wanting to use capybara + selenium to test-drive an external website like what Ryan demonstrated with capybara-mechanize...then I'm not sure. I wasn't aware capybara-mechanize allowed you to do that.
Basically, VCR will work with anything as long as you are using one of the supported HTTP client libraries (or a library built on top of one of those--like how rest-client is built on top of Net::HTTP), you have control of the ruby process where the HTTP requests are being made, and you have a way to wrap the code making the HTTP requests in a
VCR.use_cassette
call.Thanks for answer!
I haven't been able to use VCR in tests with :js => true (capybara + selenium)
The first time I run the test it passes and the cassette is recorded.
However, when I use the cassette, the test fails with Unregistered request:
POST http://127.0.0.1:7055/hub/session/..... with body '{"url":"http://subdomain.myapp.com/settings"}'
The url is different every time.
I'm using nginx locally so I can use ssl, *.myapp.com is going to 127.0.0.1:3000, I've set Capybara server_port to on 3000 and Capybara.app_host = "subdomain.myapp.com". Is that what's messing things up?
to answer my own question :):
https://www.relishapp.com/myronmarston/vcr/v/1-6-0/docs/configuration/ignore-hosts
I'm having a challenge with VCR and I hope someone can help me with that.
I have a planning API I wanted to connect to and i want to validate the data from the api with my models.
In my system an Employee has an association with with an address. To get a valid employee i need to do two requests to the API.
1. To get the employee
2. To get the address of the employee.
But VCR doesn't allow me to record 2 API calls in one function. Any idea how to handle this?
VCR is specifically designed to allow you to put as many HTTP interactions into one cassette as you want. What problem are you having?
I'd encourage you to send an email describing your issue to the mailing list, where I generally answer VCR questions.
thank you! could you make a PRO screencast with basics of TTD?
Thanks for the suggestion. I plan to cover TTD more in future pro episodes.
I am missing the iTunes announcement for this podcast?
Will it comes soon?
VCR for me has been a total game changer. Here is a snip-it to create a @vcr tag for cucumber scenarios:
This is a great start. However, it doesn't work with Scenario Outlines. The following does however:
This still doesn't work when you have cucumber backgrounds as the around hook gets executed after (!) the background is executed.
Did you manage to get a solution for this?
Thanks.
seperate before/after:
Nice. I was looking for something like this. I tried this, but get this error:
VCR 2.0 is out! Looks like lots of these ideas made it in.
For anyone having issues upgrading:
http://myronmars.to/n/dev-blog/2012/03/vcr-2-0-0-released
The ending with Capybara is like a cherry on top. Such an awesome episode :)
Was just looking for a solution while testing a portion of an application which uses google's geocoding service. We're limited to the number of geocoding requests we can make, so I turned to VCR.
I'd swear my reading comprehension is good until I attempt to read a README (no offense intended, Myron).
This screencast had me up and running moments after watching. Thanks much, Ryan and Myron!
For anyone not using rails, there is one tricky bit. here:
The
underscore
method is a rails helper, but is unnecessary here becausegsub(/[^\w\/]+/, "_")
already takes care of any non-word character that's not a slash.There seems to be no #slice method available on the example.metadata object.
undefined method `slice' for #<RSpec::Core::Metadata:0x007f9ee42ab770>
Slice is a method added by ActiveSupport to Hash, so if you're not using Rails, I'd expect you'd get a
NoMethodError
like this.However, you don't need to use Ryan's snippet to get integration with RSpec metadata--that's built in to VCR 2 now.
Ryan requested this a while ago and I was happy to oblige :).
That is extremely wonderful! Thank you so much for it.
Thanks Myron: Now my vcr_config looks like this from Ryan's:
vcr_config.rb:
and spec_helper.rb has changed the fakeweb include to webmock
require 'webmock/rspec'
What would you recommend when it comes to the /spec/vcr directory and version control?
I imagine it would be pretty safe to ignore the directory, because the cassette files would be generated on the first test run for each checkout of the repository (assuming you use record: :new_episodes)
On the other hand, if you're communicating with an unreliable server, it could be a pain to re-record the interactions correctly.
Any thoughts?
It's a matter of tradeoffs and deciding what's important to you. I tend to check my VCR cassettes into source control, because I like having the history of what the HTTP responses were at a particular point in time. It allows me to
git bisect
through my history and having passing tests. If the cassettes are not committed to source control, and the HTTP responses have changed, you'll have a very hard time running the tests at an old commit.However, committing the cassettes does tend to bloat your git repository with lots of extra files, and it makes it easy to wind up with tests that require particular exact cassettes (e.g. because you hand-edited them) to pass. I like that not committing cassettes encourages you to just treat them as a cache.
It's up to you ultimately -- just consider what is more important to you of the pros/cons I've listed here.
@rbates Are you thinking to update this one ?
VCR behavior can be modified with the flag set in the config block:
c.allow_http_connections_when_no_cassette = true
and pass through is allowed for these tests, and what I want.
I hope this helps someone else- this is a great tool thank you so much this cast and this gem.
I need to scroll to the bottom of the comments more often. I forget they are organized oddly.
I made use of the
filter_sensitive_data
option to replace a password in my cassette. This worked great the first time, but when I run the specs again, I get an error:Is there a way to deal with this problem?
Thanks for a great episode!
Louise