vcr 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +12 -0
- data/FullBuildRakeFile +22 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +46 -25
- data/Guardfile +9 -0
- data/README.md +10 -371
- data/Rakefile +6 -2
- data/TODO.md +4 -0
- data/features/support/env.rb +5 -1
- data/full_build +1 -0
- data/lib/vcr.rb +17 -7
- data/lib/vcr/basic_object.rb +39 -0
- data/lib/vcr/config.rb +4 -7
- data/lib/vcr/deprecations.rb +14 -0
- data/lib/vcr/http_stubbing_adapters/common.rb +44 -13
- data/lib/vcr/http_stubbing_adapters/fakeweb.rb +17 -28
- data/lib/vcr/http_stubbing_adapters/multi_object_proxy.rb +43 -0
- data/lib/vcr/http_stubbing_adapters/typhoeus.rb +101 -0
- data/lib/vcr/http_stubbing_adapters/webmock.rb +16 -37
- data/lib/vcr/internet_connection.rb +2 -1
- data/lib/vcr/structs.rb +32 -0
- data/lib/vcr/version.rb +1 -1
- data/spec/config_spec.rb +5 -25
- data/spec/deprecations_spec.rb +31 -3
- data/spec/extensions/net_http_spec.rb +1 -0
- data/spec/fixtures/1.9.1/fake_example.com_responses.yml +32 -1
- data/spec/fixtures/not_1.9.1/fake_example.com_responses.yml +32 -1
- data/spec/http_stubbing_adapters/fakeweb_spec.rb +9 -24
- data/spec/http_stubbing_adapters/multi_object_proxy_spec.rb +101 -0
- data/spec/http_stubbing_adapters/typhoeus_spec.rb +28 -0
- data/spec/http_stubbing_adapters/webmock_spec.rb +8 -26
- data/spec/internet_connection_spec.rb +25 -7
- data/spec/spec_helper.rb +3 -1
- data/spec/structs_spec.rb +30 -6
- data/spec/support/http_library_adapters.rb +50 -15
- data/spec/support/http_stubbing_adapter.rb +65 -56
- data/spec/support/version_checker.rb +29 -0
- data/spec/vcr_spec.rb +30 -12
- data/vcr.gemspec +5 -4
- metadata +44 -15
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.3.0 (November 11, 2010)
|
4
|
+
|
5
|
+
[Full Changelog](http://github.com/myronmarston/vcr/compare/v1.2.0...v.1.3.0)
|
6
|
+
|
7
|
+
* Moved documentation from README to [Wiki](http://github.com/myronmarston/vcr/wiki).
|
8
|
+
* Refactoring and code cleanup.
|
9
|
+
* Fix InternetConnection.available? so that it memoizes correctly when a connection is not available.
|
10
|
+
* Fix WebMock version checking to allow newly released 1.5.0 to be used without a warning.
|
11
|
+
* Add support for [Typhoeus](https://github.com/pauldix/typhoeus). Thanks to
|
12
|
+
[David Balatero](https://github.com/dbalatero) for making the necessary changes in Typhoeus
|
13
|
+
to support VCR.
|
14
|
+
|
3
15
|
## 1.2.0 (October 13, 2010)
|
4
16
|
|
5
17
|
[Full Changelog](http://github.com/myronmarston/vcr/compare/v1.1.2...v1.2.0)
|
data/FullBuildRakeFile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# this is in a separate rakefile because our main one depends on the bundled gems
|
2
|
+
# already being installed. This must be able to run w/o bundled gems installed.
|
3
|
+
|
4
|
+
desc "Run a full build: install necessary gems with bundler, runs specs, run cukes"
|
5
|
+
task :build => :ensure_bundler_installed do
|
6
|
+
sh "bundle install"
|
7
|
+
sh "rake"
|
8
|
+
end
|
9
|
+
|
10
|
+
task :ensure_bundler_installed do
|
11
|
+
installed = begin
|
12
|
+
require 'rubygems'
|
13
|
+
require 'bundler'
|
14
|
+
true
|
15
|
+
rescue LoadError
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
unless installed
|
20
|
+
sh "gem install bundler"
|
21
|
+
end
|
22
|
+
end
|
data/Gemfile
CHANGED
@@ -7,13 +7,21 @@ group :development do
|
|
7
7
|
gem 'patron', '~> 0.4.6'
|
8
8
|
gem 'em-http-request', '~> 0.2.7'
|
9
9
|
gem 'curb', '~> 0.7.8'
|
10
|
+
gem 'typhoeus', '~> 0.2.0'
|
11
|
+
end
|
12
|
+
|
13
|
+
platforms :jruby do
|
14
|
+
gem 'jruby-openssl'
|
10
15
|
end
|
11
16
|
end
|
12
17
|
|
13
18
|
# Additional gems that are useful, but not required for development.
|
14
19
|
group :extras do
|
20
|
+
gem 'guard-rspec'
|
21
|
+
|
15
22
|
platforms :mri do
|
16
23
|
gem 'rcov'
|
24
|
+
gem 'rb-fsevent'
|
17
25
|
end
|
18
26
|
|
19
27
|
platforms :mri_18 do
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vcr (1.
|
4
|
+
vcr (1.3.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -9,15 +9,17 @@ GEM
|
|
9
9
|
addressable (2.2.2)
|
10
10
|
archive-tar-minitar (0.5.2)
|
11
11
|
aruba (0.2.1)
|
12
|
+
bouncy-castle-java (1.5.0145.2)
|
12
13
|
builder (2.1.2)
|
13
14
|
columnize (0.3.1)
|
15
|
+
configuration (1.1.0)
|
14
16
|
crack (0.1.8)
|
15
|
-
cucumber (0.
|
17
|
+
cucumber (0.9.4)
|
16
18
|
builder (~> 2.1.2)
|
17
19
|
diff-lcs (~> 1.1.2)
|
18
|
-
gherkin (~> 2.
|
19
|
-
|
20
|
-
term-ansicolor (~> 1.0.
|
20
|
+
gherkin (~> 2.2.9)
|
21
|
+
json (~> 1.4.6)
|
22
|
+
term-ansicolor (~> 1.0.5)
|
21
23
|
curb (0.7.8)
|
22
24
|
diff-lcs (1.1.2)
|
23
25
|
em-http-request (0.2.12)
|
@@ -25,29 +27,43 @@ GEM
|
|
25
27
|
eventmachine (>= 0.12.9)
|
26
28
|
eventmachine (0.12.10)
|
27
29
|
fakeweb (1.3.0)
|
28
|
-
gherkin (2.
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
gherkin (2.2.9)
|
31
|
+
json (~> 1.4.6)
|
32
|
+
term-ansicolor (~> 1.0.5)
|
33
|
+
gherkin (2.2.9-java)
|
34
|
+
json (~> 1.4.6)
|
35
|
+
term-ansicolor (~> 1.0.5)
|
36
|
+
guard (0.2.2)
|
37
|
+
open_gem (~> 1.4.2)
|
38
|
+
thor (~> 0.14.3)
|
39
|
+
guard-rspec (0.1.5)
|
40
|
+
guard (>= 0.2.0)
|
32
41
|
httpclient (2.1.5.2)
|
33
|
-
|
42
|
+
jruby-openssl (0.7.2)
|
43
|
+
bouncy-castle-java
|
44
|
+
json (1.4.6)
|
45
|
+
json (1.4.6-java)
|
46
|
+
launchy (0.3.7)
|
47
|
+
configuration (>= 0.0.5)
|
48
|
+
rake (>= 0.8.1)
|
34
49
|
linecache (0.43)
|
35
50
|
linecache19 (0.5.11)
|
36
51
|
ruby_core_source (>= 0.1.4)
|
52
|
+
open_gem (1.4.2)
|
53
|
+
launchy (~> 0.3.5)
|
37
54
|
patron (0.4.9)
|
38
55
|
rack (1.1.0)
|
39
56
|
rake (0.8.7)
|
57
|
+
rb-fsevent (0.3.6)
|
40
58
|
rcov (0.9.9)
|
41
|
-
rspec (2.
|
42
|
-
rspec-core (
|
43
|
-
rspec-expectations (
|
44
|
-
rspec-mocks (
|
45
|
-
rspec-core (2.
|
46
|
-
rspec-expectations (2.
|
47
|
-
diff-lcs (
|
48
|
-
rspec-mocks (2.
|
49
|
-
rspec-core (= 2.0.0)
|
50
|
-
rspec-expectations (= 2.0.0)
|
59
|
+
rspec (2.1.0)
|
60
|
+
rspec-core (~> 2.1.0)
|
61
|
+
rspec-expectations (~> 2.1.0)
|
62
|
+
rspec-mocks (~> 2.1.0)
|
63
|
+
rspec-core (2.1.0)
|
64
|
+
rspec-expectations (2.1.0)
|
65
|
+
diff-lcs (~> 1.1.2)
|
66
|
+
rspec-mocks (2.1.0)
|
51
67
|
ruby-debug (0.10.3)
|
52
68
|
columnize (>= 0.1)
|
53
69
|
ruby-debug-base (~> 0.10.3.0)
|
@@ -64,9 +80,10 @@ GEM
|
|
64
80
|
ruby_core_source (0.1.4)
|
65
81
|
archive-tar-minitar (>= 0.5.2)
|
66
82
|
term-ansicolor (1.0.5)
|
83
|
+
thor (0.14.4)
|
67
84
|
timecop (0.3.5)
|
68
|
-
|
69
|
-
webmock (1.
|
85
|
+
typhoeus (0.2.0)
|
86
|
+
webmock (1.5.0)
|
70
87
|
addressable (>= 2.2.2)
|
71
88
|
crack (>= 0.1.7)
|
72
89
|
|
@@ -77,19 +94,23 @@ PLATFORMS
|
|
77
94
|
DEPENDENCIES
|
78
95
|
aruba (~> 0.2.1)
|
79
96
|
bundler (~> 1.0.0)
|
80
|
-
cucumber (~> 0.
|
97
|
+
cucumber (~> 0.9.4)
|
81
98
|
curb (~> 0.7.8)
|
82
99
|
em-http-request (~> 0.2.7)
|
83
100
|
fakeweb (~> 1.3.0)
|
101
|
+
guard-rspec
|
84
102
|
httpclient (~> 2.1.5.2)
|
103
|
+
jruby-openssl
|
85
104
|
patron (~> 0.4.6)
|
86
105
|
rack (= 1.1.0)
|
87
106
|
rake (~> 0.8.7)
|
107
|
+
rb-fsevent
|
88
108
|
rcov
|
89
|
-
rspec (~> 2.
|
109
|
+
rspec (~> 2.1.0)
|
90
110
|
ruby-debug
|
91
111
|
ruby-debug-base19 (= 0.11.23)
|
92
112
|
ruby-debug19
|
93
113
|
timecop (~> 0.3.5)
|
114
|
+
typhoeus (~> 0.2.0)
|
94
115
|
vcr!
|
95
|
-
webmock (
|
116
|
+
webmock (>= 1.5.0)
|
data/Guardfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at http://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch('^spec/(.*)_spec.rb')
|
6
|
+
watch('^lib/vcr.rb') { "spec/vcr_spec.rb" }
|
7
|
+
watch('^lib/vcr/(.*)\.rb') { |m| "spec/#{m[1]}_spec.rb" }
|
8
|
+
watch('^spec/spec_helper.rb') { "spec" }
|
9
|
+
end
|
data/README.md
CHANGED
@@ -2,18 +2,6 @@
|
|
2
2
|
|
3
3
|
Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.
|
4
4
|
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
gem install vcr
|
8
|
-
|
9
|
-
You'll also need either [FakeWeb](http://github.com/chrisk/fakeweb) or [WebMock](http://github.com/bblimke/webmock):
|
10
|
-
|
11
|
-
gem install fakeweb
|
12
|
-
|
13
|
-
or
|
14
|
-
|
15
|
-
gem install webmock
|
16
|
-
|
17
5
|
## Synopsis
|
18
6
|
|
19
7
|
require 'test/unit'
|
@@ -21,7 +9,7 @@ or
|
|
21
9
|
|
22
10
|
VCR.config do |c|
|
23
11
|
c.cassette_library_dir = 'fixtures/vcr_cassettes'
|
24
|
-
c.
|
12
|
+
c.stub_with :webmock # or :fakeweb
|
25
13
|
end
|
26
14
|
|
27
15
|
class VCRTest < Test::Unit::TestCase
|
@@ -49,6 +37,7 @@ maintenance) and accurate (the response from example.com will contain the same h
|
|
49
37
|
* [HTTPClient](http://github.com/nahi/httpclient) (WebMock)
|
50
38
|
* [em-http-request](http://github.com/igrigorik/em-http-request) (WebMock)
|
51
39
|
* [Net::HTTP](http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html) (FakeWeb and WebMock)
|
40
|
+
* [Typhoeus](https://github.com/pauldix/typhoeus)
|
52
41
|
* And of course any library built on Net::HTTP, such as [Mechanize](http://github.com/tenderlove/mechanize),
|
53
42
|
[HTTParty](http://github.com/jnunemaker/httparty) or [Rest Client](http://github.com/archiloque/rest-client).
|
54
43
|
* Request matching is configurable based on HTTP method, URI, host, path, body and headers.
|
@@ -59,9 +48,13 @@ maintenance) and accurate (the response from example.com will contain the same h
|
|
59
48
|
* Disables all HTTP requests that you don't explicitly allow.
|
60
49
|
* Simple cucumber integration is provided using tags.
|
61
50
|
* Known to work well with many popular ruby libraries including RSpec 1 & 2, Cucumber, Test::Unit,
|
62
|
-
Capybara, Mechanize
|
51
|
+
Capybara, Mechanize, Rest-Client and HTTParty.
|
63
52
|
* Extensively tested on 7 different ruby interpretters.
|
64
53
|
|
54
|
+
## Usage
|
55
|
+
|
56
|
+
Visit the [wiki](http://github.com/myronmarston/vcr/wiki) for usage info and documentation.
|
57
|
+
|
65
58
|
## Development
|
66
59
|
|
67
60
|
* Source hosted on [GitHub](http://github.com/myronmarston/vcr).
|
@@ -70,352 +63,7 @@ maintenance) and accurate (the response from example.com will contain the same h
|
|
70
63
|
* Pull requests are very welcome! Please include spec and/or feature coverage for every patch,
|
71
64
|
and create a topic branch for every separate change you make.
|
72
65
|
|
73
|
-
|
74
|
-
|
75
|
-
Cassettes are the medium to which VCR records HTTP interactions, and the medium from which it replays them.
|
76
|
-
While a cassette is in use, new HTTP requests (or "new episodes", as VCR calls them) either get
|
77
|
-
recorded, or an error will be raised, depending on the cassette's `:record` mode (see below). When you use
|
78
|
-
a cassette that contains previously recorded HTTP interactions, it registers them with the http stubbing
|
79
|
-
library of your choice (fakeweb or webmock) so that HTTP requests get the recorded response. Between test
|
80
|
-
runs, cassettes are stored on disk as YAML files in your configured cassette library directory.
|
81
|
-
|
82
|
-
Each cassette acts a bit like a sandbox: it has an effect on HTTP requests during the current test while it
|
83
|
-
is inserted, but has no effect on the rest of your test suite.
|
84
|
-
|
85
|
-
Cassettes can be configured with a few options:
|
86
|
-
|
87
|
-
* `:record`: Specifies a record mode for this cassette.
|
88
|
-
* `:erb`: Used for dynamic cassettes (see below for more details).
|
89
|
-
* `:match_requests_on`: An array of request attributes to match on (see below for more details).
|
90
|
-
* `:re_record_interval`: Controls automatic re-recording of the cassette (see below for more details).
|
91
|
-
|
92
|
-
## Record modes
|
93
|
-
|
94
|
-
VCR supports 3 record modes. You can set a default record mode in your configuration (see below)
|
95
|
-
and a per-cassette record mode when inserting a cassette. The record modes are:
|
96
|
-
|
97
|
-
* `:new_episodes`: Previously recorded HTTP interactions will be replayed. New HTTP interactions will be recorded.
|
98
|
-
This is generally the most useful mode. VCR will automatically record and replay new HTTP requests as your
|
99
|
-
codebase evolves to make new requests.
|
100
|
-
* `:all`: Previously recorded HTTP interactions will be ignored. All HTTP interactions will be recorded.
|
101
|
-
This is useful if you're interested in using VCR to log your HTTP interactions but don't care to ever replay
|
102
|
-
them. Alternately, you can temporarily change your record mode to `:all` to force it to re-record all requests.
|
103
|
-
* `:none`: Previously recorded HTTP interactions will be replayed. New HTTP interactions will result in an error.
|
104
|
-
This mode is useful when your code makes potentially dangerous HTTP requests (i.e. it hits a production
|
105
|
-
server rather than a sandbox/staging server), as it will prevent any new requests from completing, raising
|
106
|
-
an error instead. Generally, you will temporarily use the `:new_episodes` or `:all` record modes
|
107
|
-
to perform the initial recording before changing it to `:none`.
|
108
|
-
|
109
|
-
When no cassette is inserted, all HTTP requests will result in a `Real HTTP connections are disabled` error.
|
110
|
-
|
111
|
-
## Request Matching
|
112
|
-
|
113
|
-
In order to properly replay previously recorded requests, VCR must match new HTTP requests to a previously
|
114
|
-
recorded one. By default, it matches on HTTP method and URI, since that is usually deterministic and
|
115
|
-
fully identifies the resource and action for typical RESTful APIs. In some cases (such as SOAP webservices)
|
116
|
-
this may not work so well, and VCR allows you to customize how requests are matched.
|
117
|
-
|
118
|
-
Cassettes take a `:match_requests_on` option that expects an array of request attributes to match on.
|
119
|
-
Supported attributes are:
|
120
|
-
|
121
|
-
* `:method`: The HTTP method (i.e. GET, POST, PUT or DELETE) of the request.
|
122
|
-
* `:uri`: The full URI of the request.
|
123
|
-
* `:host`: The host of the URI. You can use this (alone, or in combination with `:path`) as an alternative
|
124
|
-
to `:uri` to cause VCR to match using a regex that matches the host.
|
125
|
-
* `:path`: The path of the URI. You can use this (alone, or in combination with `:host`) as an alternative
|
126
|
-
to `:uri` to cause VCR to match using a regex that matches the path.
|
127
|
-
* `:body`: The body of the request.
|
128
|
-
* `:headers`: The request headers.
|
129
|
-
|
130
|
-
By default, VCR uses a `:match_requests_on` option like:
|
131
|
-
|
132
|
-
:match_requests_on => [:uri, :method]
|
133
|
-
|
134
|
-
If you want to match on another attribute, just add it to the array:
|
135
|
-
|
136
|
-
:match_requests_on => [:uri, :method, :body]
|
137
|
-
|
138
|
-
Note that FakeWeb cannot match on `:body` or `:headers`. In general, it is recommended that you configure
|
139
|
-
your cassettes to match on the most specific set of attributes that is deterministic.
|
140
|
-
|
141
|
-
## Configuration
|
142
|
-
|
143
|
-
require 'vcr'
|
144
|
-
|
145
|
-
VCR.config do |c|
|
146
|
-
c.cassette_library_dir = 'fixtures/cassette_library'
|
147
|
-
c.http_stubbing_library = :fakeweb
|
148
|
-
c.ignore_localhost = true
|
149
|
-
c.default_cassette_options = { :record => :none }
|
150
|
-
end
|
151
|
-
|
152
|
-
This can go pretty much wherever, as long as this code is run before your tests, specs or scenarios. I tend
|
153
|
-
to put it in `spec/support/vcr.rb`, `test/support/vcr.rb` or `features/support/vcr.rb`. You can set the following
|
154
|
-
configuration options:
|
155
|
-
|
156
|
-
* `cassette_library_dir`: VCR will save the cassette YAML files to this directory. If you are using Rails 3 and
|
157
|
-
ActiveRecord YAML fixtures, you will probably want to avoid putting VCR cassettes in a sub-directory of
|
158
|
-
`RAILS_ROOT/test/fixtures`. Rails will assume your cassette YAML files are ActiveRecord fixtures and raise an
|
159
|
-
error when the content doesn't conform to its expectations.
|
160
|
-
* `http_stubbing_library`: Which http stubbing library to use. Currently `:fakeweb` and `:webmock` are supported.
|
161
|
-
VCR will automatically configure FakeWeb/WebMock for you; you do not need to reference either one at all.
|
162
|
-
* `ignore_localhost`: Defaults to false. Setting it true does the following:
|
163
|
-
* Localhost requests will proceed as normal. The "Real HTTP connections are disabled" error will not occur.
|
164
|
-
* Localhost requests will not be recorded.
|
165
|
-
* Previously recorded localhost requests will not be replayed.
|
166
|
-
* `default_cassette_options`: The default options for your cassettes. These will be overridden by any options you
|
167
|
-
set on each individual cassette.
|
168
|
-
|
169
|
-
## Usage with your favorite ruby test/spec framework
|
170
|
-
|
171
|
-
VCR can easily be used with any ruby test or spec framework. Usually, you'll want to use `VCR.use_cassette`:
|
172
|
-
|
173
|
-
VCR.use_cassette('geocoding/Seattle, WA', :record => :new_episodes) do
|
174
|
-
# do something that makes an HTTP request
|
175
|
-
end
|
176
|
-
|
177
|
-
Alternately, with a framework like [shoulda](http://github.com/thoughtbot/shoulda), you can insert and eject a
|
178
|
-
cassette with individual method calls from setup and teardown:
|
179
|
-
|
180
|
-
context "Some object that makes an HTTP request" do
|
181
|
-
setup do
|
182
|
-
VCR.insert_cassette('geocoding/Seattle, WA', :record => :new_episodes)
|
183
|
-
end
|
184
|
-
|
185
|
-
should "make an HTTP request" do
|
186
|
-
# ...
|
187
|
-
end
|
188
|
-
|
189
|
-
should "make another HTTP request" do
|
190
|
-
# ...
|
191
|
-
end
|
192
|
-
|
193
|
-
teardown do
|
194
|
-
VCR.eject_cassette
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
## Usage with RSpec
|
199
|
-
|
200
|
-
If you're using RSpec, you can use a special macro provided by VCR:
|
201
|
-
|
202
|
-
describe MyApiClient do
|
203
|
-
context "create" do
|
204
|
-
# Pass use_vcr_cassette the same args you would pass VCR.use_cassette.
|
205
|
-
use_vcr_cassette "my_api_client/create", :record => :new_episodes
|
206
|
-
|
207
|
-
it "makes an HTTP request"
|
208
|
-
it "makes another HTTP request"
|
209
|
-
end
|
210
|
-
|
211
|
-
context "destroy" do
|
212
|
-
# You can leave off the cassette name and it will be inferred from the example group
|
213
|
-
# descriptions--in this case "MyApiClient/destroy".
|
214
|
-
# You can also leave off the options hash--the configured default options will be used.
|
215
|
-
use_vcr_cassette :record => :new_episodes, :match_requests_on => [:uri, :method, :body]
|
216
|
-
|
217
|
-
it "makes an HTTP request"
|
218
|
-
it "makes another HTTP request"
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
To use this, you need to configure RSpec to make the `use_vcr_cassette` available as a macro.
|
223
|
-
Here's how to do that for RSpec 1:
|
224
|
-
|
225
|
-
require 'vcr'
|
226
|
-
|
227
|
-
Spec::Runner.configure do |c|
|
228
|
-
c.extend VCR::RSpec::Macros
|
229
|
-
end
|
230
|
-
|
231
|
-
Or for RSpec 2:
|
232
|
-
|
233
|
-
require 'vcr'
|
234
|
-
|
235
|
-
RSpec.configure do |c|
|
236
|
-
c.extend VCR::RSpec::Macros
|
237
|
-
end
|
238
|
-
|
239
|
-
## Usage with Cucumber
|
240
|
-
|
241
|
-
VCR provides additional support for cucumber. You can of course use `VCR.use_cassette` within a step definition,
|
242
|
-
and that's the recommended way for any of your custom step definitions. But many times I find myself using generic
|
243
|
-
step definitions provided by another library (such as the webrat/capybara web steps generated by cucumber-rails),
|
244
|
-
and you don't want to modify these. VCR provides cucumber tagging support to help in these cases.
|
245
|
-
|
246
|
-
First, tag your scenario with something descriptive:
|
247
|
-
|
248
|
-
@facebook_http_request
|
249
|
-
Scenario: Sign up with facebook connect
|
250
|
-
|
251
|
-
Then let VCR know about this tag, in `features/support/vcr.rb` (or some similar support file):
|
252
|
-
|
253
|
-
VCR.cucumber_tags do |t|
|
254
|
-
t.tags '@facebook_http_request', '@twitter_status_update', :record => :none
|
255
|
-
t.tags '@another_scenario_tag'
|
256
|
-
end
|
257
|
-
|
258
|
-
For each of the tags you specify in your `cucumber_tags` block, VCR will set up an appropriate
|
259
|
-
[After hook](http://wiki.github.com/aslakhellesoy/cucumber/hooks) to use a cassette
|
260
|
-
for the entire scenario. The tag (minus the '@') will be used as the cassette name, and it'll
|
261
|
-
go in the `cucumber_tags` subdirectory of the configured cassette library directory.
|
262
|
-
|
263
|
-
If the last argument to `#tags` is a hash, VCR will use it as the options for the named cassettes.
|
264
|
-
|
265
|
-
## Usage with Capybara
|
266
|
-
|
267
|
-
When you use any of the javascript-enabled drivers (selenium, celerity, culerity) with
|
268
|
-
[capybara](http://github.com/jnicklas/capybara), it'll need to ping the app running on localhost.
|
269
|
-
Set the `ignore_localhost` option to true to allow this.
|
270
|
-
|
271
|
-
## Cassette Customization
|
272
|
-
|
273
|
-
Cassettes are stored as simple plain text YAML files and can easily be edited to suit your needs. One common need
|
274
|
-
is for a particular request to be stubbed using a regex rather than the raw URL. This is handy for URLs that contain
|
275
|
-
non-deterministic portions (such as timestamps)--since the URL will be a bit different each time, the URL from the
|
276
|
-
recorded request will not match the URL for future requests. You can simply change the URL to the YAML of the
|
277
|
-
appropriate regex.
|
278
|
-
|
279
|
-
Figure out the yaml in irb:
|
280
|
-
|
281
|
-
>> require 'yaml'
|
282
|
-
=> true
|
283
|
-
>> puts /example\.com\/\d+/.to_yaml
|
284
|
-
--- !ruby/regexp /example\.com\/\d+/
|
285
|
-
|
286
|
-
Edit your cassette file:
|
287
|
-
|
288
|
-
request: !ruby/struct:VCR::Request
|
289
|
-
method: :get
|
290
|
-
uri: !ruby/regexp /example\.com\/\d+/
|
291
|
-
body:
|
292
|
-
headers:
|
293
|
-
|
294
|
-
Note that it may be simpler (and better!) to use the `:match_requests_on` cassette option with `:host` and/or `:path`,
|
295
|
-
as that gives you a a URL regex without the need to manually edit the cassette file. If you do change a url to a regex
|
296
|
-
in a cassette file, VCR will use it, regardless of the `:match_requests_on` setting.
|
297
|
-
|
298
|
-
## Dynamic Cassettes
|
299
|
-
|
300
|
-
VCR's default recording and replaying is static. The exact response that is initially recorded will
|
301
|
-
be replayed for all future requests. Usually this is fine, but in some cases you need something more
|
302
|
-
dynamic. You can use [ERB](http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/) for this.
|
303
|
-
|
304
|
-
Enable ERB evaluation of a cassette using the `:erb` option:
|
305
|
-
|
306
|
-
VCR.use_cassette('user-subscription', :erb => true) do
|
307
|
-
# do something that makes an HTTP request
|
308
|
-
end
|
309
|
-
|
310
|
-
You can use variables in your cassette's ERB by passing a hash:
|
311
|
-
|
312
|
-
VCR.use_cassette('user-subscription', :erb => { :user => User.last }) do
|
313
|
-
# do something that makes an HTTP request
|
314
|
-
end
|
315
|
-
|
316
|
-
In your cassette:
|
317
|
-
|
318
|
-
request: !ruby/struct:VCR::Request
|
319
|
-
method: :get
|
320
|
-
uri: http://some-domain.com:80/users/<%= user.id %>
|
321
|
-
body:
|
322
|
-
headers:
|
323
|
-
...
|
324
|
-
response: !ruby/struct:VCR::Response
|
325
|
-
...
|
326
|
-
body: Hello, <%= user.name %>!
|
327
|
-
|
328
|
-
## Automatic cassette re-recording
|
329
|
-
|
330
|
-
Over time, your cassettes may get out-of-date. APIs change and sites you scrape get updated. VCR provides
|
331
|
-
a facility to automatically re-record your cassettes. You enable re-recording using the
|
332
|
-
`:re_record_interval` option:
|
333
|
-
|
334
|
-
A_WEEK = 7 * 24 * 60 * 60 # or use 7.days if you're using ActiveSupport
|
335
|
-
|
336
|
-
VCR.use_cassette('my_cassette', :re_record_interval => A_WEEK) { ... }
|
337
|
-
|
338
|
-
If the cassette file was last modified more than 7 days ago, VCR will use the `:all` record mode (regardless
|
339
|
-
of the configured record mode) to allow new HTTP requests and record them. VCR will check to make sure you
|
340
|
-
have an internet connection before doing this, so if you are running the tests without one, the automatic
|
341
|
-
re-recording will not kick in.
|
342
|
-
|
343
|
-
## FakeWeb or WebMock?
|
344
|
-
|
345
|
-
VCR works fine with either FakeWeb or WebMock. Overall, WebMock has more features, and you'll need to use
|
346
|
-
WebMock if you want to use VCR with an HTTP library besides Net::HTTP. However, FakeWeb is currently
|
347
|
-
about three times faster than WebMock, so you may want to stick with FakeWeb if you don't need WebMock's
|
348
|
-
additional features. You can see the
|
349
|
-
[benchmarks](http://github.com/myronmarston/vcr/blob/master/benchmarks/http_stubbing_libraries.rb) for
|
350
|
-
more details.
|
351
|
-
|
352
|
-
You should not need to directly interact with either FakeWeb or WebMock. VCR will take care of disallowing
|
353
|
-
http connections when no cassette is inserted, and it will clean up all stubs/registrations when a cassette
|
354
|
-
is ejected. If you ever decide to switch HTTP stubbing libraries, you'll just have to update the VCR config
|
355
|
-
setting.
|
356
|
-
|
357
|
-
## Suggested Workflow
|
358
|
-
|
359
|
-
First, configure VCR as I have above. I like setting the default record mode to `:none`
|
360
|
-
so that no new HTTP requests are made without me explicitly allowing it, but if you may prefer to
|
361
|
-
set it to `:new_episodes`.
|
362
|
-
|
363
|
-
When an HTTP request is made, you'll get an error such as:
|
364
|
-
|
365
|
-
Real HTTP connections are disabled. Unregistered request: get http://example.com
|
366
|
-
|
367
|
-
Find the place that is making the HTTP request (the backtrace should help here). If you've already recorded this HTTP
|
368
|
-
request to a cassette from a different test, you can simply re-use the cassette. Use `VCR.use_cassette`, as
|
369
|
-
shown above. You may also want to refactor this into a helper method that sets up the VCR cassette and does whatever
|
370
|
-
makes the HTTP request:
|
371
|
-
|
372
|
-
def set_user_address(user, address, city, state)
|
373
|
-
VCR.use_cassette("geocoding/#{address}, #{city}, #{state}", :record => :new_episodes) do
|
374
|
-
user.address.update_attributes!(:address => address, :city => city, :state => state)
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
In this case, I've used a dynamic cassette name based on the address being geocoded. That way, each separate address
|
379
|
-
gets a different cassette, and tests that set the same user address will reuse the same cassette. I've also set
|
380
|
-
the record mode to `:new_episodes` so that VCR will automatically record geocoding requests for a new address
|
381
|
-
to a new cassette, without me having to change any code.
|
382
|
-
|
383
|
-
If the HTTP request that triggered the error is new, you'll have to record it for the first time. Simply use
|
384
|
-
`VCR.use_cassette` with the record mode set to `:new_episodes` or `:all`. Run the test again, and VCR will
|
385
|
-
record the HTTP interaction. I usually remove the record mode at this point so that it uses the default
|
386
|
-
of `:none` in the future. Future test runs will get the recorded response, and if your code changes so
|
387
|
-
that it is making a new HTTP request, you'll be notified by an error as shown above.
|
388
|
-
|
389
|
-
VCR is designed to be used very granularly. Rather than inserting a global cassette, I recommend you wrap individual
|
390
|
-
blocks of code in `VCR.use_cassette` and record logically grouped sets of requests.
|
391
|
-
|
392
|
-
## Ruby Interpreter Compatibility
|
393
|
-
|
394
|
-
VCR has been tested on the following ruby interpreters:
|
395
|
-
|
396
|
-
* MRI 1.8.6-p399
|
397
|
-
* MRI 1.8.7-p302
|
398
|
-
* MRI 1.9.1-p378
|
399
|
-
* MRI 1.9.2-p0
|
400
|
-
* REE 1.8.7-2010.02
|
401
|
-
* JRuby 1.5.1
|
402
|
-
* Rubinius 1.1
|
403
|
-
|
404
|
-
## Notes, etc.
|
405
|
-
|
406
|
-
* The objects serialized to the cassette YAML files changed with the 0.4 release. Cassettes recorded with
|
407
|
-
older versions of VCR will not work with VCR 0.4.0 and later. However, VCR provides a rake task to migrate
|
408
|
-
your old cassettes to the new format--see the [changelog](http://github.com/myronmarston/vcr/blob/master/CHANGELOG.md)
|
409
|
-
for more info.
|
410
|
-
* The cassette name determines the name of the library file for the given cassette. Strings or symbols are fine,
|
411
|
-
and you can include any characters, but spaces and invalid file name characters will be removed
|
412
|
-
before the cassette reads or writes to its library file.
|
413
|
-
* You can use a directory separator (i.e. '/') in your cassette names to cause it to use a subdirectory
|
414
|
-
of the cassette library directory. The cucumber tagging support uses this.
|
415
|
-
* VCR maintains a simple stack of cassettes. This allows you to nest them as deeply as you want.
|
416
|
-
This is particularly useful when you have a cucumber step definition that uses a cassette, and
|
417
|
-
you also want to use a cassette for the entire scenario using the tagging support.
|
418
|
-
* If you find VCR useful, please recommend me on [working with rails](http://workingwithrails.com/person/16590-myron-marston).
|
66
|
+
If you find VCR useful, please recommend me on [working with rails](http://workingwithrails.com/person/16590-myron-marston).
|
419
67
|
|
420
68
|
## Thanks
|
421
69
|
|
@@ -424,6 +72,8 @@ VCR has been tested on the following ruby interpreters:
|
|
424
72
|
* [Chris Kampmeier](http://github.com/chrisk) for [FakeWeb](http://github.com/chrisk/fakeweb).
|
425
73
|
* [Chris Young](http://github.com/chrisyoung) for [NetRecorder](http://github.com/chrisyoung/netrecorder),
|
426
74
|
the inspiration for VCR.
|
75
|
+
* [David Balatero](https://github.com/dbalatero) for help with [Typhoeus](https://github.com/pauldix/typhoeus)
|
76
|
+
support.
|
427
77
|
|
428
78
|
Thanks also to the following people who have contributed patches or helpful suggestions:
|
429
79
|
|
@@ -432,17 +82,6 @@ Thanks also to the following people who have contributed patches or helpful sugg
|
|
432
82
|
* [Ben Hutton](http://github.com/benhutton)
|
433
83
|
* [Eric Allam](http://github.com/rubymaverick)
|
434
84
|
|
435
|
-
## Similar Libraries
|
436
|
-
|
437
|
-
If VCR doesn't meet your needs, please [open an issue](http://github.com/myronmarston/vcr/issues) and let me know
|
438
|
-
how VCR could be improved. You may also want to try one of these similar libraries:
|
439
|
-
|
440
|
-
* [Stale Fish](http://github.com/jsmestad/stale_fish)
|
441
|
-
* [NetRecorder](http://github.com/chrisyoung/netrecorder)
|
442
|
-
* [Ephemeral Response](http://github.com/sandro/ephemeral_response)
|
443
|
-
* [Net::HTTP Spy](http://github.com/martinbtt/net-http-spy)
|
444
|
-
* [WebFixtures](http://github.com/trydionel/web_fixtures)
|
445
|
-
|
446
85
|
## Copyright
|
447
86
|
|
448
87
|
Copyright (c) 2010 Myron Marston. See LICENSE for details.
|