Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Updated README.

  • Loading branch information...
commit 20ec03431933a93a6d341c651dbb2c76d05795cb 1 parent 1679d4f
Myron Marston authored March 03, 2010

Showing 1 changed file with 61 additions and 23 deletions. Show diff stats Hide diff stats

  1. 84  README.rdoc
84  README.rdoc
Source Rendered
... ...
@@ -1,7 +1,7 @@
1 1
 = VCR
2 2
 
3 3
 VCR provides helpers to record HTTP requests for URIs that are not registered with fakeweb, and replay them later.
4  
-It provides built-in support for cucumber, but works with any ruby testing framework.
  4
+It works with any ruby testing framework and provides built-in support for cucumber.
5 5
 
6 6
 == Installation
7 7
 
@@ -12,7 +12,10 @@ It provides built-in support for cucumber, but works with any ruby testing frame
12 12
 This README assumes you are familiar with FakeWeb; if not, please checkout the {README}[http://github.com/chrisk/fakeweb/blob/master/README.rdoc].
13 13
 
14 14
 VCR was inspired by {NetRecorder}[http://github.com/chrisyoung/netrecorder], but was designed from the ground up to support
15  
-localized recording and replaying, rather than the global recording and replaying of NetRecorder.
  15
+localized recording and replaying, rather than the global recording and replaying of NetRecorder.  In general, I believe that
  16
+tests should not rely upon anything global.  You're coupling your test to something outside of it that may later change and
  17
+break the test.  It's far better to localize things to each test, as much as possible.  VCR, in combination with FakeWeb,
  18
+makes it easy to do this with the recording and replying of HTTP responses.
16 19
 
17 20
 == Cassettes
18 21
 
@@ -24,7 +27,7 @@ the following:
24 27
 * It register these responses with fakeweb (depending on the cassette's :record option--see below)
25 28
 * It sets the <tt>FakeWeb.allow_net_connect</tt> setting based on the cassette's :record option.
26 29
 
27  
-While a cassette is active, any HTTP requests to a URL of a previously recorded responses will use get
  30
+While a cassette is active, any HTTP requests to a URL of a previously recorded response will use
28 31
 the recorded response.  New HTTP requests (i.e. HTTP requests that have not been previously recorded)
29 32
 will be recorded to the same cache file, depending on your :record option.  When you destroy a cassette,
30 33
 it does the following:
@@ -35,27 +38,29 @@ it does the following:
35 38
 
36 39
 == Record modes
37 40
 
38  
-VCR supports 3 record modes, which configures when it records new responses.  You can set a default
  41
+VCR supports 3 record modes, which configure when it records new responses.  You can set a default
39 42
 record mode in your configuration (see below) and a per-cassette record mode when creating a cassette.  The record
40 43
 modes are:
41 44
 
42  
-* :all - This will cause VCR to re-record all HTTP requests that occur while the cassette is the current one.
  45
+* <tt>:all</tt> - This will cause VCR to re-record all HTTP requests that occur.
43 46
   When the cassette is created, it will not register any of the cached responses with fakeweb.
44  
-  <tt>FakeWeb.allow_net_connect</tt> will be set to true, so it can record the requests.
45  
-* :none - This will prevent VCR from recording, or even allowing, any new HTTP requests while the cassette is the current one.
  47
+  <tt>FakeWeb.allow_net_connect</tt> will be set to true, so it can record the requests.  Use this
  48
+  when you want to re-record all of the HTTP requests for a cassette.  Alternately, you can simply
  49
+  delete the corresponding cache file and use the :unregistered record mode, described below.
  50
+* <tt>:none</tt> - This will prevent VCR from recording, or even allowing, any new HTTP requests.
46 51
   The previously recorded responses will be registered with fakeweb.  <tt>FakeWeb.allow_net_connect</tt> will be set to
47  
-  false, so that no new HTTP connections are allowed.
48  
-* :unregistered - This will use the previously recorded responses, and record any new requests that are not registered with
  52
+  false, so that no new HTTP connections are allowed.  Use this when you want to guarantee that no external
  53
+  HTTP requests will be made while the given cassette is active.  Fakeweb will raise an error in this case.
  54
+* <tt>:unregistered</tt> - This will use the previously recorded responses, and record any new requests that are not registered with
49 55
   fakeweb.  The previously recorded responses will be registered with fakeweb.  <tt>FakeWeb.allow_net_connect</tt> will be
50  
-  set to true, so that VCR will record any new HTTP requests within the cassette.
51  
-
52  
-Note that :none and :unregistered will usually at the same.  The difference is when your code changes and
53  
-it makes a new HTTP request that wasn't made when the cassette was first recorded.  With :none, you would
54  
-get an error from FakeWeb (since allow_net_connect is set to false).  With :unregistered, the new response
55  
-would get saved in the cassette's yaml file, and automatically get used in the future.
  56
+  set to true, so that VCR will record any new HTTP requests within the cassette.  Use this when it's ok for external HTTP
  57
+  requests to be made without you explicitly allowing it.  New requests will get saved to the cassettes yml file, and
  58
+  automatically get used in the future.
56 59
 
57 60
 == Configuration
58 61
 
  62
+  require 'vcr'
  63
+
59 64
   # Set the default allow_net_connect option--usually you'll want this off.
60 65
   # You don't usually want your test suite to make HTTP connections, do you?
61 66
   FakeWeb.allow_net_connect = false
@@ -68,11 +73,12 @@ would get saved in the cassette's yaml file, and automatically get used in the f
68 73
     c.default_cassette_record_mode = :none
69 74
   end
70 75
 
71  
-This can go pretty much wherever, as long as this code is run before your tests, specs or scenarios.
  76
+This can go pretty much wherever, as long as this code is run before your tests, specs or scenarios.  I tend
  77
+to put it in spec/support/vcr.rb, test/support/vcr.rb or features/support/vcr.rb.
72 78
 
73 79
 == Usage with your favorite test/spec framework
74 80
 
75  
-VCR can easily be used with any ruby test/spec framework.  Usually, you'll want to use <tt>VCR.with_cassette</tt>:
  81
+VCR can easily be used with any ruby test or spec framework.  Usually, you'll want to use <tt>VCR.with_cassette</tt>:
76 82
 
77 83
   VCR.with_cassette('geocoding/Seattle, WA', :record => :unregistered) do
78 84
     # do something that causes an HTTP request.
@@ -100,25 +106,57 @@ cache dir.  The :record setting is optional--if you leave it blank, your configu
100 106
 VCR provides special support for cucumber.  You can of course use <tt>VCR.with_cassette</tt> within a step definition,
101 107
 and that's the recommended way for any of your step definitions.  But many times I find myself using generic step definitions
102 108
 provided by another library (such as the webrat/capybara web steps generated by cucumber-rails), and I don't want to modify
103  
-these.  VCR provides cucumber tagging support to help in these cases:
  109
+these.  VCR provides cucumber tagging support to help in these cases.
  110
+
  111
+First, tag your scenario with something descriptive:
104 112
 
105  
-  # in a cucumber feature file...
106 113
   @facebook_http_request
107 114
   Scenario: Sign up with facebook connect
108 115
 
109  
-  # in features/support/vcr.rb (or some similar support file)
  116
+Then let VCR know about this tag, in features/support/vcr.rb (or some similar support file):
  117
+
110 118
   VCR.cucumber_tags do |t|
111 119
     t.tags '@facebook_http_request', '@twitter_status_update', :record => :none
112 120
     t.tags '@another_scenario_tag'   # the default record mode will be used for this tag.
113 121
   end
114 122
 
115  
-  # Note: you'd probably also want to put your VCR config in this file (see above).
116  
-
117 123
 For each of the tags you specify in your cucumber_tags block, VCR will set up the appropriate
118 124
 {Before and After hooks}[http://wiki.github.com/aslakhellesoy/cucumber/hooks] to use a cassette
119 125
 for the entire scenario.  The tag (minus the '@') will be used as the cassette name, and it'll
120 126
 go in the cucumber_tags subdirectory of the configured cache dir.
121 127
 
  128
+== Suggested Workflow
  129
+
  130
+First, configure VCR and FakeWeb as I have above.  I like setting <tt>FakeWeb.allow_net_connect</tt> to <tt>false</tt>
  131
+and VCR's <tt>default_cassette_record_mode</tt> to <tt>:none</tt> so that no new HTTP requests are made without me
  132
+explicitly allowing it.
  133
+
  134
+When an HTTP request is made, you'll get an {error from FakeWeb}[http://github.com/chrisk/fakeweb/blob/fakeweb-1.2.8/lib/fake_web/ext/net_http.rb#L62-63],
  135
+such as:
  136
+
  137
+  FakeWeb::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: get http://example.com
  138
+
  139
+Find the place that is making the HTTP request (the backtrace should help here).  If you've already recorded this HTTP
  140
+request to a cassette from a different test, you can simply re-use the cassette.  Use <tt>VCR.with_cassette</tt>, as
  141
+shown above.  You may also want to refactor this into a helper method that sets up the VCR cassette and does whatever
  142
+makes the HTTP request:
  143
+
  144
+  def set_user_address(user, address, city, state)
  145
+    VCR.with_cassette("geocoding/#{address}, #{city}, #{state}", :record => :unregistered) do
  146
+      user.address.update_attributes!(:address => address, :city => city, :state => state)
  147
+    end
  148
+  end
  149
+
  150
+In this case, I've used a dynamic cassette name based on the address being geocoded.  That way, each separate address
  151
+gets a different cassette, and tests that set the same user address will reuse the same cassette.  I've also set
  152
+the record mode to <tt>:unregistered</tt> so that VCR will automatically record geocoding requests for a new address
  153
+to a new cassette, without me having to do anything.
  154
+
  155
+If the HTTP request that triggered the error is new, you'll have to record it for the first time.  Simply use <tt>VCR.with_cassette</tt>
  156
+with the record mode set to <tt>:unregistered</tt> or <tt>:all</tt>.  Run the test again, and VCR will record the HTTP response.  I usually
  157
+remove the record mode at this point so that it uses the default of <tt>:none</tt> in the future.  Future test runs will use the
  158
+recorded response, and if your code changes so that it is making a new HTTP request, you'll get the same FakeWeb error as shown above.
  159
+
122 160
 == Ruby Version Compatibility
123 161
 
124 162
   specs.should pass if RUBY_VERSION =~ /^1.(8.6|8.7|9.1)$/
@@ -130,7 +168,7 @@ go in the cucumber_tags subdirectory of the configured cache dir.
130 168
   before the cassette reads or writes to the file.
131 169
 * You can use a directory separator (i.e. '/') in your cassette names to cause it to use a subdirectory
132 170
   of the cache_dir.  The cucumber tagging support uses this.
133  
-* VCR maintains a simple stack of cassette.  This allows you to nest them as deeply as you want.
  171
+* VCR maintains a simple stack of cassettes.  This allows you to nest them as deeply as you want.
134 172
   This is particularly useful when you have a cucumber step definition that uses a cassette, and
135 173
   you also want to use a cassette for the entire scenario using the tagging support.
136 174
 

0 notes on commit 20ec034

Please sign in to comment.
Something went wrong with that request. Please try again.