Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 290 lines (227 sloc) 7.978 kB
59e1d92 @myronmarston Add an upgrade guide.
authored
1 See the [Changelog](changelog) for a complete list of changes from VCR
2 1.x to 2.0. This file simply lists the most pertinent ones to upgrading.
3
14e7730 @myronmarston Flesh out Upgrade.md.
authored
4 ## Supported Rubies
5
6 Ruby 1.8.6 and 1.9.1 are no longer supported.
7
59e1d92 @myronmarston Add an upgrade guide.
authored
8 ## Configuration Changes
9
10 In VCR 1.x, your configuration block would be something like this:
11
12 ``` ruby
13 VCR.config do |c|
14 c.cassette_library_dir = 'cassettes'
15 c.stub_with :fakeweb, :typhoeus
16 end
17 ```
18
19 This will continue to work in VCR 2.0 but will generate deprecation
20 warnings. Instead, you should change this to:
21
22 ``` ruby
23 VCR.configure do |c|
24 c.cassette_library_dir = 'cassettes'
25 c.hook_into :fakeweb, :typhoeus
26 end
27 ```
28
29 ## New Cassette Format
30
31 The cassette format has changed between VCR 1.x and VCR 2.0.
32 VCR 1.x cassettes cannot be used with VCR 2.0.
33
34 The easiest way to upgrade is to simply delete your cassettes and
35 re-record all of them. VCR also provides a rake task that attempts
36 to upgrade your 1.x cassettes to the new 2.0 format. To use it, add
37 the following line to your Rakefile:
38
39 ``` ruby
40 load 'vcr/tasks/vcr.rake'
41 ```
42
43 Then run `rake vcr:migrate_cassettes DIR=path/to/your/cassettes/directory` to
44 upgrade your cassettes. Note that this rake task may be unable to
45 upgrade some cassettes that make extensive use of ERB. In addition, now
46 that VCR 2.0 does less normalization then before, it may not be able to
47 migrate the cassette perfectly. It's recommended that you delete and
48 re-record your cassettes if you are able.
49
14e7730 @myronmarston Flesh out Upgrade.md.
authored
50 ## Custom Request Matchers
51
1e1b5b0 @myronmarston Clarify a few things in the Upgrade doc.
authored
52 VCR 2.0 allows you to register custom request matchers:
14e7730 @myronmarston Flesh out Upgrade.md.
authored
53
54 ``` ruby
55 VCR.configure do |c|
56 c.register_request_matcher :port do |request_1, request_2|
57 URI(request_1.uri).port == URI(request_2.uri).port
58 end
59 end
60 ```
61
1e1b5b0 @myronmarston Clarify a few things in the Upgrade doc.
authored
62 You can also pass any callable (an object that responds to #call, such as a lambda)
63 to the `:match_requests_on` option:
64
65 ``` ruby
66 port_matcher = lambda do |request_1, request_2|
67 URI(request_1.uri).port == URI(request_2.uri).port
68 end
69
70 VCR.use_cassette("example", :match_requests_on => [:host, port_matcher, :method]) do
71 # make an HTTP request
72 end
73 ```
74
14e7730 @myronmarston Flesh out Upgrade.md.
authored
75 In addition, a helper method is provided for generating a custom
76 matcher that ignores one or more query parameters:
77
78 ``` ruby
79 uri_without_timestamp = VCR.request_matchers.uri_without_param(:timestamp)
80 VCR.configure do |c|
81 c.register_request_matcher(:uri_without_timestamp, &uri_without_timestamp)
82 end
83 ```
84
85 ## Custom Serializers
86
87 VCR 2.0 supports multiple serializers. `:yaml`, `:json`, `:psych` and
88 `:syck` are supported out of the box, and it's easy to implement your
1e1b5b0 @myronmarston Clarify a few things in the Upgrade doc.
authored
89 own. Custom serializers must implement `#file_extension`, `#serialize`
90 and `#deserialize`:
14e7730 @myronmarston Flesh out Upgrade.md.
authored
91
92 ``` ruby
93 VCR.use_cassette("example", :serialize_with => :json) do
94 # make an HTTP request
95 end
96
97 marshal_serializer = Object.new
98 marshal_serializer.instance_eval do
99 def file_extension
100 "marsh"
101 end
102
103 def serialize(hash)
104 Marshal.dump(hash)
105 end
106
107 def deserialize(string)
108 Marshal.load(string)
109 end
110 end
111
112 VCR.configure do |c|
113 c.cassette_serializers[:marshal] = serializer
114 c.default_cassette_options = { :serialize_with => :marshal }
115 end
116 ```
117
118 ## Request Hooks
119
120 VCR 2.0 has new request hooks, allowing you to inject custom logic
121 before an HTTP request, after an HTTP request, or around an HTTP
122 request:
123
124 ``` ruby
125 VCR.configure do |c|
126 c.before_http_request do |request|
127 # do something with the request
128 end
129
130 c.after_http_request do |request, response|
131 # do something with the request or response
132 end
133
134 # around_http_request only works on ruby 1.9
1e1b5b0 @myronmarston Clarify a few things in the Upgrade doc.
authored
135 c.around_http_request do |request|
136 uri = URI(request.uri)
137 if uri.host == 'api.geocoder.com'
138 # extract an address like "1700 E Pine St, Seattle, WA"
139 # from a query like "address=1700+E+Pine+St%2C+Seattle%2C+WA"
140 address = CGI.unescape(uri.query.split('=').last)
141 VCR.use_cassette("geocoding/#{address}", &request)
142 else
143 request.proceed
14e7730 @myronmarston Flesh out Upgrade.md.
authored
144 end
145 end
146 end
147 ```
148
149 ## Ignore a Request Based on Anything
150
151 You can now define what requests get ignored using a block. This
152 gives you the flexibility to ignore a requets based on anything.
153
154 ``` ruby
155 VCR.configure do |c|
156 c.ignore_request do |request|
157 uri = URI(request.uri)
158 uri.host == 'localhost' && uri.port == 7500
159 end
160 end
161 ```
162
163 ## Integration with RSpec 2 Metadata
164
165 VCR can integrate directly with RSpec metadata:
166
167 ``` ruby
168 VCR.configure do |c|
169 c.configure_rspec_metadata!
170 end
171
172 RSpec.configure do |c|
173 # so we can use `:vcr` rather than `:vcr => true`;
174 # in RSpec 3 this will no longer be necessary.
175 c.treat_symbols_as_metadata_keys_with_true_values = true
176 end
177
178 # apply it to an example group
179 describe MyAPIWrapper, :vcr do
180 end
181
182 describe MyAPIWrapper do
183 # apply it to an individual example
184 it "does something", :vcr do
185 end
186
187 # set some cassette options
188 it "does something", :vcr => { :record => :new_episodes } do
189 end
190
191 # override the cassette name
192 it "does something", :vcr => { :cassette_name => "something" } do
193 end
194 end
195 ```
196
197 ## Improved Faraday Integration
198
199 VCR 1.x integrated with Faraday but required that you insert
200 `VCR::Middleware::Faraday` into your middleware stack and configure
201 `stub_with :faraday`. VCR 2 now takes care of inserting itself
202 into the Faraday middleware stack if you configure `hook_into :faraday`.
203
204 ## Improved Unhandled Error Messages
205
206 When VCR is unsure how to handle a request, the error message now contains
207 suggestions for how you can configure VCR or your test so it can handle
208 the request.
209
210 ## Debug Logger
211
e0c462d @myronmarston Fix typo.
authored
212 VCR 2.0 has a new configuration option that will turn on a logging mode
14e7730 @myronmarston Flesh out Upgrade.md.
authored
213 so you can get more insight into what VCR is doing, for troubleshooting
214 purposes:
215
216 ``` ruby
217 VCR.configure do |c|
218 c.debug_logger = File.open('log/vcr.log')
219 # or...
220 c.debug_logger = $stderr
221 end
222 ```
223
224 ## Playback Changes
225
226 In VCR 1.x, a single HTTP interaction could be played back multiple
227 times. This was mostly due to how VCR was implemented using FakeWeb
228 and WebMock, and was not really by design. It's more in keeping with
229 the philosophy of VCR to record the entire sequence of HTTP interactions
230 (including the duplicate requests). In VCR 2, each recorded HTTP
231 interaction can only be played back once unless you use the new
232 `:allow_playback_repeats` option.
233
b3cea43 @myronmarston Add note to upgrade document about change in the :uri matcher.
authored
234 In VCR 1.x, request matching was delegated to the HTTP stubbing library
235 (typically FakeWeb or WebMock). They contain some normalization logic
236 that can treat some URIs that are different strings as equivalent.
237 For example, WebMock ignores the ordering of query parameters:
238
239 ``` ruby
240 > require 'webmock'
241 => true
242 > uri1 = "http://foo.com/bar?a=1&b=2"
243 => "http://foo.com/bar?a=1&b=2"
244 > uri2 = "http://foo.com/bar?b=2&a=1"
245 => "http://foo.com/bar?b=2&a=1"
246 > uri1 == uri2
247 => false
248 > WebMock::Util::URI.normalize_uri(uri1) == WebMock::Util::URI.normalize_uri(uri2)
249 => true
250 ```
251
252 VCR 2, the `:uri` matcher simply [uses string
d46736e @myronmarston A couple more documentation tweaks.
authored
253 equality](https://github.com/myronmarston/vcr/blob/v2.0.0/lib/vcr/request_matcher_registry.rb#L111).
b3cea43 @myronmarston Add note to upgrade document about change in the :uri matcher.
authored
254 This means that there are some cases of non-deterministic URIs that VCR
255 1.x matched but VCR 2.0 will not match. If you need the `:uri` matcher
256 to be tolerant of slight variations like these, you can easily override
257 it:
258
259 ``` ruby
260 VCR.configure do |c|
261 c.register_request_matcher(:uri) do |r1, r2|
262 WebMock::Util::URI.normalize_uri(r1.uri) == WebMock::Util::URI.normalize_uri(r2.uri)
263 end
264 end
265 ```
266
994a236 @myronmarston Words.
authored
267 ## Preserve Exact Body Bytes
268
269 Sometimes the request or response body of an HTTP interaction cannot
270 be serialized and deserialized properly. Usually this is due to the body
271 having invalid UTF-8 bytes. This new option configures VCR to base64
272 encode the body in order to preserve the bytes exactly. It can either
273 be configured globally with a block, or set on individual cassettes:
274
275 ``` ruby
276 VCR.configure do |c|
277 c.preserve_exact_body_bytes do |http_message|
278 http_message.body.encoding.name == 'ASCII-8BIT' ||
279 !http_message.body.valid_encoding?
280 end
281 end
282
283 # or....
284
285 VCR.use_cassette("my_cassette", :preserve_exact_body_bytes => true) do
286 # ...
287 end
288 ```
289
Something went wrong with that request. Please try again.