go-vcr alternatives and similar packages
Based on the "Testing Frameworks" category.
Alternatively, view go-vcr alternatives based on common mentions on social networks and blogs.
-
Testify
A toolkit with common assertions and mocks that plays nicely with the standard library -
GoConvey
Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go. -
gnomock
Test your code without writing mocks with ephemeral Docker containers 📦 Setup popular services with just a couple lines of code ⏱️ No bash, no yaml, only code 💻 -
testfixtures
Ruby on Rails like test fixtures for Go. Write tests against a real database -
embedded-postgres
Run a real Postgres database locally on Linux, OSX or Windows as part of another Go application or test -
gotest.tools
A collection of packages to augment the go testing package and support common patterns. -
testza
Full-featured test framework for Go! Assertions, fuzzing, input testing, output capturing, and much more! 🍕 -
go-testdeep
Extremely flexible golang deep comparison, extends the go testing package, tests HTTP APIs and provides tests suite -
dbcleaner
Clean database for testing, inspired by database_cleaner for Ruby -
GoSpec
Testing framework for Go. Allows writing self-documenting tests/specifications, and executes them concurrently and safely isolated. [UNMAINTAINED] -
jsonassert
A Go test assertion library for verifying that two representations of JSON are semantically equal -
testcase
testcase is an opinionated testing framework to support test driven design. -
assert
:exclamation:Basic Assertion Library used along side native go testing, with building blocks for custom assertions -
gogiven
gogiven - BDD testing framework for go that generates readable output directly from source code -
schema
Quick and easy expression matching for JSON schemas used in requests and responses
Static code analysis for 29 languages.
Do you think we are missing an alternative of go-vcr or a related project?
Popular Comparisons
README
go-vcr
go-vcr
simplifies testing by recording your HTTP interactions and
replaying them in future runs in order to provide fast, deterministic
and accurate testing of your code.
go-vcr
was inspired by the VCR library for Ruby.
Installation
Install go-vcr
by executing the command below:
$ go get -v gopkg.in/dnaeon/go-vcr.v3/recorder
Note, that if you are migrating from a previous version of go-vcr
,
you need re-create your test cassettes, because as of go-vcr v3
there is a new format of the cassette, which is not
backwards-compatible with older releases.
Usage
Please check the [examples](./examples) from this repo for example
usage of go-vcr
.
You can also refer to the [test cases](./recorder/recorder_test.go) for additional examples.
Custom Request Matching
During replay mode, You can customize the way incoming requests are
matched against the recorded request/response pairs by defining a
MatcherFunc
function.
For example, the following matcher will match on method, URL and body:
func customMatcher(r *http.Request, i Request) bool {
if r.Body == nil || r.Body == http.NoBody {
return cassette.DefaultMatcher(r, i)
}
var reqBody []byte
var err error
reqBody, err = io.ReadAll(r.Body)
if err != nil {
log.Fatal("failed to read request body")
}
r.Body.Close()
r.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))
return r.Method == i.Method && r.URL.String() == i.URL && string(reqBody) == i.Body
}
func recorderWithCustomMatcher() {
rec, err := recorder.New("fixtures/matchers")
if err != nil {
log.Fatal(err)
}
defer rec.Stop() // Make sure recorder is stopped once done with it
rec.SetReplayableInteractions(true)
rec.SetMatcher(customMatcher)
client := rec.GetDefaultClient()
resp, err := client.Get("https://www.google.com/")
...
...
...
}
Hooks
Hooks in go-vcr
are regular functions which take an HTTP interaction
and are invoked in different stages of the playback.
You can use hooks to modify a request/response before it is saved on disk, before it is returned to the client, or anything else that you might want to do with it, e.g. you might want to simply log each captured interaction.
You often provide sensitive data, such as API credentials, when making requests against a service.
By default, this data will be stored in the recorded data but you probably don't want this.
Removing or replacing data before it is stored can be done by adding
one or more Hook
s to your Recorder
.
There are different kinds of hooks, which are invoked in different
stages of the playback. The supported hook kinds are
AfterCaptureHook
, BeforeSaveHook
and BeforeResponseReplayHook
.
Here is an example that removes the Authorization
header from all
requests right after capturing a new interaction.
r, err := recorder.New("fixtures/filters")
if err != nil {
log.Fatal(err)
}
defer r.Stop() // Make sure recorder is stopped once done with it
// Add a hook which removes Authorization headers from all requests
hook := func(i *cassette.Interaction) error {
delete(i.Request.Headers, "Authorization")
return nil
}
r.AddHook(hook, recorder.AfterCaptureHook)
Hooks added using recorder.AfterCaptureHook
are applied right after
an interaction is captured and added to the in-memory cassette. This
may not always be what you need. For example if you modify an
interaction using this hook kind then subsequent test code will see
the edited response.
For instance, if a response body contains an OAuth access token that
is needed for subsequent requests, then redacting the access token
using a AfterCaptureHook
will result in authorization failures in
subsequent test code.
In such cases you would want to modify the recorded interactions right
before they are saved on disk. For that purpose you should be using a
BeforeSaveHook
, e.g.
r, err := recorder.New("fixtures/filters")
if err != nil {
log.Fatal(err)
}
defer r.Stop() // Make sure recorder is stopped once done with it
// Your test code will continue to see the real access token and
// it is redacted before the recorded interactions are saved on disk
hook := func(i *cassette.Interaction) error {
if strings.Contains(i.Request.URL, "/oauth/token") {
i.Response.Body = `{"access_token": "[REDACTED]"}`
}
return nil
}
r.AddHook(hook, recorder.BeforeSaveHook)
Passing Through Requests
Sometimes you want to allow specific requests to pass through to the remote server without recording anything.
Globally, you can use ModePassthrough
for this, but if you want to
disable the recorder for individual requests, you can add
Passthrough
handlers to the recorder.
The function takes a pointer to the original request, and returns a boolean, indicating if the request should pass through to the remote server.
Here's an example to pass through requests to a specific endpoint:
// Passthrough the request to the remote server if the path matches "/login".
r.AddPassthrough(func(req *http.Request) bool {
return req.URL.Path == "/login"
})
License
go-vcr
is Open Source and licensed under the
BSD License
*Note that all licence references and agreements mentioned in the go-vcr README section above
are relevant to that project's source code only.