Title: | Record 'HTTP' Calls to Disk |
Version: | 2.0.0 |
Description: | Record test suite 'HTTP' requests and replays them during future runs. A port of the Ruby gem of the same name (https://github.com/vcr/vcr/). Works by recording real 'HTTP' requests/responses on disk in 'cassettes', and then replaying matching responses on subsequent requests. |
License: | MIT + file LICENSE |
URL: | https://github.com/ropensci/vcr/, https://books.ropensci.org/http-testing/, https://docs.ropensci.org/vcr/ |
BugReports: | https://github.com/ropensci/vcr/issues |
Depends: | R (≥ 4.1) |
Imports: | cli, curl (≥ 6.3.0), jsonlite, lifecycle, R6, rlang (≥ 1.1.0), rprojroot, waldo, yaml |
Suggests: | crul (≥ 1.6.0), desc, httr, httr2 (≥ 1.1.2), knitr, qs2, rmarkdown, roxygen2 (≥ 7.2.1), testthat (≥ 3.0.0), webfakes, withr |
VignetteBuilder: | knitr |
Config/testthat/edition: | 3 |
Config/testthat/parallel: | true |
Config/testthat/start-first: | ause_cassette_re_record |
Encoding: | UTF-8 |
Language: | en-US |
RoxygenNote: | 7.3.2 |
X-schema.org-applicationCategory: | Web |
X-schema.org-isPartOf: | https://ropensci.org |
X-schema.org-keywords: | http, https, API, web-services, curl, mock, mocking, http-mocking, testing, testing-tools, tdd |
NeedsCompilation: | no |
Packaged: | 2025-07-23 05:06:34 UTC; sckott |
Author: | Scott Chamberlain |
Maintainer: | Scott Chamberlain <myrmecocystus@gmail.com> |
Repository: | CRAN |
Date/Publication: | 2025-07-23 12:24:48 UTC |
vcr: Record 'HTTP' Calls to Disk
Description
Record test suite 'HTTP' requests and replays them during future runs. A port of the Ruby gem of the same name (https://github.com/vcr/vcr/). Works by recording real 'HTTP' requests/responses on disk in 'cassettes', and then replaying matching responses on subsequent requests.
Backstory
A Ruby gem of the same name (VCR
, https://github.com/vcr/vcr) was
created many years ago and is the original. Ports in many languages
have been done. Check out that GitHub repo for all the details on
how the canonical version works.
Main functions
The use_cassette()
function is most likely what you'll want to use. It
sets the cassette you want to record to, inserts the cassette, and then
ejects the cassette, recording the interactions to the cassette.
Alternatively, you can use insert_cassette()
for more control, but then
you have to make sure to use eject_cassette()
.
vcr configuration
vcr_configure()
is the function to use to set R session-wide settings.
See its manual file for help.
Async
As of crul v1.5, vcr
will work for async http requests with
crul. httr does not do async requests, and httr2
async plumbing does not have any hooks for mocking via webmockr
or recording real requests via this package.
Author(s)
Maintainer: Scott Chamberlain myrmecocystus@gmail.com (ORCID)
Authors:
Aaron Wolen (ORCID)
Maëlle Salmon (ORCID)
Daniel Possenriede (ORCID)
Hadley Wickham hadley@posit.co
Other contributors:
rOpenSci (019jywm96) [funder]
See Also
Useful links:
Report bugs at https://github.com/ropensci/vcr/issues
Cassette handler
Description
Main R6 class that is called from the main user facing
function use_cassette()
Value
An R6 Cassette
pbject.
Public fields
name
(character) cassette name
record
(character) record mode
serialize_with
(character) serializer (yaml|json|qs2)
serializer
(Serializer) serializer (YAML|JSON|QS2)
match_requests_on
(character) matchers to use
re_record_interval
(numeric) the re-record interval
root_dir
root dir, gathered from
vcr_configuration()
preserve_exact_body_bytes
(logical) Whether to base64 encode the bytes of the requests and responses
http_interactions
(list) internal use
new_interactions
(boolean) Have any interactions been recorded?
warn_on_empty
(logical) warn if no interactions recorded
new_cassette
is this a new cassette?
Methods
Public methods
Method new()
Create a new Cassette
object
Usage
Cassette$new( name, dir = NULL, record = NULL, match_requests_on = NULL, serialize_with = NULL, preserve_exact_body_bytes = NULL, re_record_interval = NULL, warn_on_empty = NULL )
Arguments
name
The name of the cassette. vcr will sanitize this to ensure it is a valid file name.
dir
The directory where the cassette will be stored.
record
The record mode. Default: "once".
match_requests_on
HTTP request components to use when matching.
serialize_with
(character) Which serializer to use. Valid values are "yaml" (default), "json", and "qs2".
preserve_exact_body_bytes
(logical) Whether or not to base64 encode the bytes of the requests and responses for this cassette when serializing it. See also
preserve_exact_body_bytes
invcr_configure()
. Default:FALSE
re_record_interval
(numeric) When given, the cassette will be re-recorded at the given interval, in seconds.
warn_on_empty
Warn when ejecting the cassette if no interactions have been recorded.
Returns
A new Cassette
object
Method insert()
insert the cassette
Usage
Cassette$insert()
Returns
self
Method eject()
ejects the cassette
Usage
Cassette$eject()
Returns
self
Method print()
print method for Cassette
objects
Usage
Cassette$print(x, ...)
Arguments
x
self
...
ignored
Method file()
get the file path for the cassette
Usage
Cassette$file()
Returns
character
Method recording()
Is the cassette in recording mode?
Usage
Cassette$recording()
Returns
logical
Method replaying()
Is the cassette in replaying mode?
Usage
Cassette$replaying()
Returns
logical
Method remove_outdated_interactions()
Remove outdated interactions
Usage
Cassette$remove_outdated_interactions()
Method record_http_interaction()
record an http interaction (doesn't write to disk)
Usage
Cassette$record_http_interaction(request, response)
Arguments
request
A
vcr_request
.response
A
vcr_response
.
Returns
an interaction as a list with request and response slots
Method clone()
The objects of this class are cloneable with this method.
Usage
Cassette$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
See Also
vcr_configure()
, use_cassette()
, insert_cassette()
Request handlers
Description
These are internal classes that should not be used by users.
List cassettes, get current cassette, etc.
Description
List cassettes, get current cassette, etc.
Usage
cassettes()
current_cassette()
current_cassette_recording()
current_cassette_replaying()
cassette_path()
Details
-
cassettes()
: returns all active cassettes in the current session. -
current_cassette()
: returnsNULL
when no cassettes are in use; returns the current cassette (aCassette
object) when one is in use -
currrent_cassette_recording()
andcurrent_cassette_replaying()
: tell you if the current cassette is recording and/or replaying. They both returnFALSE
if there is no cassette in use. -
cassette_path()
: returns the current directory path where cassettes will be stored
Examples
vcr_configure(dir = tempdir())
# list all cassettes
cassettes()
# list the currently active cassette
insert_cassette("stuffthings")
current_cassette()
cassettes()
eject_cassette()
cassettes()
# list the path to cassettes
cassette_path()
vcr_configure(dir = file.path(tempdir(), "foo"))
cassette_path()
vcr_configure_reset()
Check cassette names
Description
This function has been deprecated because it's not possible for it to detect re-used cassette names 100% correctly and the problem of duplicated cassette names is relatively easy to debug by hand.
Usage
check_cassette_names(
pattern = "test-",
behavior = "stop",
allowed_duplicates = NULL
)
Arguments
pattern |
(character) regex pattern for file paths to check.
This is done inside of |
behavior |
(character) "stop" (default) or "warning". If "warning",
we use |
allowed_duplicates |
(character) Cassette names that can be duplicated. |
Manually insert and eject a cassette
Description
Generally you should not need to use these functions, instead preferring
use_cassette()
or local_cassette()
Usage
insert_cassette(
name,
dir = NULL,
record = NULL,
match_requests_on = NULL,
serialize_with = NULL,
preserve_exact_body_bytes = NULL,
re_record_interval = NULL,
warn_on_empty = NULL
)
eject_cassette()
Arguments
name |
The name of the cassette. This is used to name a file on disk, so it must be valid file name. |
dir |
The directory where the cassette will be stored. Defaults to
|
record |
Record mode that dictates how HTTP requests/responses are recorded. Possible values are:
|
match_requests_on |
Character vector of request matchers used to
determine which recorded HTTP interaction to replay. The default matches
on the The full set of possible values are:
If more than one is specified, all components must match in order for the
request to match. If not supplied, defaults to Note that the request header and body will only be included in the
cassette if |
serialize_with |
(string) Which serializer to use:
|
preserve_exact_body_bytes |
(logical) Force a binary (base64)
representation of the request and response bodies? By default, vcr
will look at the |
re_record_interval |
(integer) How frequently (in seconds) the
cassette should be re-recorded. Default: |
warn_on_empty |
(logical) Warn if the cassette is ejected but no interactions
have been recorded. Default: |
Value
A Cassette, invisibly.
Examples
vcr_configure(dir = tempdir())
insert_cassette("hello")
current_cassette()
eject_cassette()
current_cassette()
Use cassettes in examples
Description
insert_example_cassette()
is a wrapper around insert_cassette()
that
stores cassettes in inst/_vcr/
. Call it in the first line of your examples
(typically wrapped in \dontshow{}
), and call eject_cassette()
on the
last line.
Run the example manually once to record the vignettte, then it will be
replayed during R CMD check
, ensuring that your example no longer uses
the internet.
Usage
insert_example_cassette(
name,
package,
record = NULL,
match_requests_on = NULL,
serialize_with = NULL,
preserve_exact_body_bytes = NULL,
re_record_interval = NULL
)
Arguments
name |
The name of the cassette. This is used to name a file on disk, so it must be valid file name. |
package |
Package name. |
record |
Record mode. This will be To re-record all cassettes, you can delete |
match_requests_on |
Character vector of request matchers used to
determine which recorded HTTP interaction to replay. The default matches
on the The full set of possible values are:
If more than one is specified, all components must match in order for the
request to match. If not supplied, defaults to Note that the request header and body will only be included in the
cassette if |
serialize_with |
(string) Which serializer to use:
|
preserve_exact_body_bytes |
(logical) Force a binary (base64)
representation of the request and response bodies? By default, vcr
will look at the |
re_record_interval |
(integer) How frequently (in seconds) the
cassette should be re-recorded. Default: |
Examples
# In this example I'm showing the insert and eject commands, but you'd
# usually wrap these in \dontshow{} so the user doesn't see them and
# think that they're something they need to copy.
insert_example_cassette("httpbin-get", package = "vcr")
req <- httr2::request("https://hb.cran.dev/get")
resp <- httr2::req_perform(req)
str(httr2::resp_body_json(resp))
eject_cassette()
Determine if vcr is recording/replaying
Description
local_cassette()
and use_cassette()
set the VCR_IS_RECORDING
and VCR_IS_REPLAYING
environment variables to make it easy to determine
vcr state without taking a dependency on vcr. These functions show you
how to use them; we expect you to copy and paste these functions into your
own package
Usage
is_recording()
is_replaying()
Value
TRUE
or FALSE
.
Turn vcr on and off
Description
-
turn_on()
andturn_off()
turn on and off for the whole session. -
turned_off(code)
temporarily turns off whilecode
is running, guaranteeing that you make a real HTTP request. -
turned_on()
reports on if vcr is turned on or not. -
skip_if_vcr_off()
skips a test if vcr is turned off. This is occasionally useful if you're using a cassette to simulate a faked request, or if the real request would return different values (e.g. you're testing date parsing and the request returns the current date).
You can also control the default behaviour in a new session by setting the following environment variables before R starts:
Use
VCR_TURN_OFF=true
to suppress all vcr usage, ignoring all cassettes. This is useful for CI/CD workflows where you want to ensure the test suite is run against the live API.Set
VCR_TURNED_OFF=true
to turn off vcr, but still use cassettes.
Usage
turn_on()
turn_off(ignore_cassettes = FALSE)
turned_off(code, ignore_cassettes = FALSE)
turned_on()
skip_if_vcr_off()
Arguments
ignore_cassettes |
(logical) Controls what happens when a cassette is
inserted while vcr is turned off. If |
code |
Any block of code to run, presumably an HTTP request. |
Examples
# By default, vcr is turned on
turned_on()
# you can turn off for the rest of the session
turn_off()
turned_on()
# turn on again
turn_on()
# or just turn it on turn off temporarily
turned_off({
# some HTTP requests here
turned_on()
})
Use vcr in vignettes
Description
setup_knitr()
registers a knitr hook to make it easy to use vcr inside a
vignette. First call setup_knitr()
in your setup chunk (or other chunk
early in the document):
```{r setup} #| include: false vcr::setup_knitr() ```
Then, in a chunk where you want to use a cassette, set the cassette
chunk
option to the name of the cassette:
```{r} #| cassette: name req <- httr2::request("http://r-project.org") resp <- httr2::req_perform(req) ```
Or if you have labelled the chunk, you can use cassette: true
to use the
chunk label as the cassette name:
```{r} #| label: cassette-name #| cassette: true req <- httr2::request("http://r-project.org") resp <- httr2::req_perform(req) ```
You can build your vignettes however you usually do (from the command line, with pkgdown, with RStudio/Positron, etc).
Usage
setup_knitr(prefix = NULL, dir = "_vcr", ...)
Arguments
prefix |
An prefix for the cassette name to make cassettes unique across vignettes. Defaults to the file name (without extension) of the currently executing vignette. |
dir |
Directory where to create the cassette file. Default: '"_vcr"“. |
... |
Other arguments passed on to |
Use a cassette to record HTTP requests
Description
use_cassette(...)
uses a cassette for the code in ...
;
local_cassette()
uses a cassette for the current function scope (e.g.
for one test). Learn more in vignette("vcr")
.
Note that defaults for most arguments are controlled by vcr_configure()
,
so you may want to use that instead if you are changing the defaults for
all cassettes.
Usage
use_cassette(
name,
...,
dir = NULL,
record = NULL,
match_requests_on = NULL,
serialize_with = NULL,
preserve_exact_body_bytes = NULL,
re_record_interval = NULL,
warn_on_empty = NULL
)
local_cassette(
name,
dir = NULL,
record = NULL,
match_requests_on = NULL,
serialize_with = NULL,
preserve_exact_body_bytes = NULL,
re_record_interval = NULL,
warn_on_empty = NULL,
frame = parent.frame()
)
Arguments
name |
The name of the cassette. This is used to name a file on disk, so it must be valid file name. |
... |
a block of code containing one or more requests (required). Use
curly braces to encapsulate multi-line code blocks. If you can't pass a code
block use |
dir |
The directory where the cassette will be stored. Defaults to
|
record |
Record mode that dictates how HTTP requests/responses are recorded. Possible values are:
|
match_requests_on |
Character vector of request matchers used to
determine which recorded HTTP interaction to replay. The default matches
on the The full set of possible values are:
If more than one is specified, all components must match in order for the
request to match. If not supplied, defaults to Note that the request header and body will only be included in the
cassette if |
serialize_with |
(string) Which serializer to use:
|
preserve_exact_body_bytes |
(logical) Force a binary (base64)
representation of the request and response bodies? By default, vcr
will look at the |
re_record_interval |
(integer) How frequently (in seconds) the
cassette should be re-recorded. Default: |
warn_on_empty |
(logical) Warn if the cassette is ejected but no interactions
have been recorded. Default: |
frame |
Attach exit handlers to this environment. Typically, this
should be either the current environment or a parent frame (accessed
through |
See Also
insert_cassette()
and eject_cassette()
for the underlying
functions.
Setup vcr for a package
Description
use_vcr()
is deprecated because it is no longer needed. In lifecycle v2,
local_cassette()
and friends automatically use tests/testthat/_vcr
without any need for additional configuration.
Usage
use_vcr(dir = ".", verbose = TRUE)
Arguments
dir |
(character) path to package root. default's to current directory |
verbose |
(logical) print progress messages. default: |
Details
Sets a minimum vcr version, which is usually the latest (stable) version on CRAN. You can of course easily remove or change the version requirement yourself after running this function.
Value
only messages about progress, returns invisible()
Global Configuration Options
Description
Configurable options that define vcr's default behavior.
Usage
vcr_configure(
dir,
record,
match_requests_on,
serialize_with,
json_pretty,
ignore_hosts,
ignore_localhost,
preserve_exact_body_bytes,
turned_off,
re_record_interval,
log,
log_opts,
filter_sensitive_data,
filter_sensitive_data_regex,
filter_request_headers,
filter_response_headers,
filter_query_parameters,
write_disk_path,
warn_on_empty_cassette
)
local_vcr_configure(..., .frame = parent.frame())
vcr_configure_reset()
vcr_configuration()
vcr_config_defaults()
Arguments
dir |
Directory where cassettes are stored. |
record |
Record mode that dictates how HTTP requests/responses are recorded. Possible values are:
|
match_requests_on |
Character vector of request matchers used to
determine which recorded HTTP interaction to replay. The default matches
on the The full set of possible values are:
If more than one is specified, all components must match in order for the
request to match. If not supplied, defaults to Note that the request header and body will only be included in the
cassette if |
serialize_with |
(string) Which serializer to use:
|
json_pretty |
(logical) want JSON to be newline separated to be easier
to read? Or remove newlines to save disk space? default: |
ignore_hosts |
(character) Vector of hosts to ignore. e.g.,
|
ignore_localhost |
(logical) Default: |
preserve_exact_body_bytes |
(logical) Force a binary (base64)
representation of the request and response bodies? By default, vcr
will look at the |
turned_off |
(logical) VCR is turned on by default. Default:
|
re_record_interval |
(integer) How frequently (in seconds) the
cassette should be re-recorded. Default: |
log , log_opts |
See |
filter_sensitive_data , filter_sensitive_data_regex |
Transform header and/or body in the request and response.
Named list of substitutions to apply to the headers and body of the
request and response. Format is |
filter_request_headers , filter_response_headers |
Filter request or response headers. Should be a list:
unnamed components are removed, and named components are transformed.
For example, httr2's redacted headers are automatically removed. |
filter_query_parameters |
Filter query parameters in the request. A list where unnamed components
are removed, and named components are transformed. For example,
|
write_disk_path |
(character) path to write files to
for any requests that write responses to disk. By default this will be
|
warn_on_empty_cassette |
(logical) Should a warning be thrown when an
empty cassette is detected? Empty cassettes are cleaned up (deleted) either
way. This option only determines whether a warning is thrown or not.
Default: |
... |
Configuration settings used to override defaults. |
.frame |
Attach exit handlers to this environment. Typically, this
should be either the current environment or a parent frame (accessed
through |
Examples
vcr_configure(dir = tempdir())
vcr_configure(dir = tempdir(), record = "all")
vcr_configuration()
vcr_config_defaults()
vcr_configure(dir = tempdir(), ignore_hosts = "google.com")
vcr_configure(dir = tempdir(), ignore_localhost = TRUE)
# filter sensitive data
vcr_configure(dir = tempdir(),
filter_sensitive_data = list(foo = "<bar>")
)
vcr_configure(dir = tempdir(),
filter_sensitive_data = list(foo = "<bar>", hello = "<world>")
)
Configure vcr logging
Description
By default, logging is disabled, but you can easily enable for the
entire session with vcr_configure_log()
or for just one test with
local_vcr_configure_log()
.
Usage
vcr_configure_log(
log = TRUE,
file = stderr(),
include_date = NULL,
log_prefix = "Cassette"
)
local_vcr_configure_log(
log = TRUE,
file = stderr(),
include_date = NULL,
log_prefix = "Cassette",
frame = parent.frame()
)
Arguments
log |
Should we log important vcr things? |
file |
A path or connection to log to |
include_date |
(boolean) Include date and time in each log entry. |
log_prefix |
"Cassette". We insert the cassette name after this prefix, followed by the rest of the message. |
frame |
Attach exit handlers to this environment. Typically, this
should be either the current environment or a parent frame (accessed
through |
Examples
# The default logs to stderr()
vcr_configure_log()
# But you might want to log to a file
vcr_configure_log(file = file.path(tempdir(), "vcr.log"))
Retrieve last vcr request/response
Description
When debugging, it's often useful to see the last request and response
respectively. These functions give you what would have been recorded to disk
or replayed from disk. If the last request wasn't recorded, and there was
no matching request, vcr_last_response
will return NULL
.
Usage
vcr_last_request()
vcr_last_response()
Locate file in tests directory
Description
This function, similar to testthat::test_path()
, is designed to work both
interactively and during tests, locating files in the tests/
directory.
Usage
vcr_test_path(...)
Arguments
... |
Character vectors giving path components. Each character string
gets added to the path, e.g., |
Value
A character vector giving the path
Note
vcr_test_path()
assumes you are using testthat for your unit tests.
Examples
if (interactive()) {
vcr_test_path("fixtures")
}