golang实现HTTP请求录制与回放的离线测试插件库govcr的使用
Golang实现HTTP请求录制与回放的离线测试插件库govcr的使用
govcr是一个用于记录和回放HTTP/HTTPS交互的Go库,主要用于离线单元测试、行为测试和集成测试,也可以用于API模拟。
简单示例
// 完整示例请参考测试中的TestExample1
func TestExample1() {
vcr := govcr.NewVCR(
govcr.NewCassetteLoader("MyCassette1.json"),
govcr.WithRequestMatchers(govcr.NewMethodURLRequestMatchers()...), // 使用"宽松"的请求匹配器
)
vcr.Client.Get("http://example.com/foo")
}
第一次运行此示例时,MyCassette1.json
文件不存在,TestExample1
会进行真实的HTTP调用。
在后续执行中(除非删除cassette文件),HTTP调用将从cassette回放,不会发生真实的HTTP调用。
注意:我们使用"宽松"的请求匹配器是因为example.com
注入了一个随请求变化的"Age"头。如果没有修改器,govcr默认的严格匹配器将无法匹配cassette上的track,并继续发送实时请求(并将其记录到cassette)。
安装
go get github.com/seborama/govcr/v17@latest
在代码中使用以下导入:
import "github.com/seborama/govcr/v17"
核心概念
govcr是Go http.Client
的包装器。它可以将实时HTTP流量记录到文件(称为"cassettes"),并稍后从这些文件回放HTTP请求(“tracks”)而不是进行实时HTTP调用。
当使用govcr的http.Client
时,请求会与cassette上的tracks匹配:
- 如果cassette上存在匹配的track,则播放该track
- 否则请求会执行到HTTP服务器的实时调用,然后记录到cassette供下次使用
完整示例
自定义HTTP客户端
// 完整示例请参考测试中的TestExample2
func TestExample2() {
// 为应用创建自定义http.Transport
tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true, // 仅示例,不推荐
}
// 创建myApp实例
app := &myApp{
httpClient: &http.Client{
Transport: tr,
Timeout: 15 * time.Second,
},
}
// 实例化VCR
vcr := govcr.NewVCR(
govcr.NewCassetteLoader(exampleCassetteName2),
govcr.WithClient(app.httpClient),
)
// 注入VCR的http.Client包装器
app.httpClient = vcr.HTTPClient()
// 运行请求并显示统计信息
app.Get("https://example.com/foo")
}
加密cassette
// 完整示例请参考测试中的TestExample4
vcr := govcr.NewVCR(
govcr.NewCassetteLoader(exampleCassetteName4).
WithCipher(
encryption.NewChaCha20Poly1305WithRandomNonceGenerator,
"test-fixtures/TestExample4.unsafe.key"),
)
自定义请求匹配器
vcr.SetRequestMatchers(
govcr.DefaultMethodMatcher,
govcr.DefaultURLMatcher,
func(httpRequest, trackRequest *track.Request) bool {
// 可以安全地修改输入:
// 修改会影响其他RequestMatcher,但不会影响原始HTTP请求或cassette Tracks
httpRequest.Header.Del("X-Custom-Timestamp")
trackRequest.Header.Del("X-Custom-Timestamp")
return govcr.DefaultHeaderMatcher(httpRequest, trackRequest)
},
)
回放track修改器
// 完整示例请参考测试中的TestExample3
vcr := govcr.NewVCR(
govcr.NewCassetteLoader(exampleCassetteName3),
govcr.WithRequestMatchers(
func(httpRequest, trackRequest *track.Request) bool {
// 从比较中移除头部
httpRequest.Header.Del("X-Transaction-Id")
trackRequest.Header.Del("X-Transaction-Id")
return govcr.DefaultHeaderMatcher(httpRequest, trackRequest)
},
),
govcr.WithTrackReplayingMutators(
track.ResponseDeleteHeaderKeys("X-Transaction-Id"), // 不追加到现有值
track.ResponseTransferHTTPHeaderKeys("X-Transaction-Id"),
),
)
运行模式
govcr支持多种操作模式:
- 正常HTTP模式:从cassette回放如果有匹配的track,否则进行实时调用
- 仅实时模式:从不从cassette回放
- 离线模式:仅从cassette回放,如果没有匹配的track则返回传输错误
- 只读模式:正常行为,但禁止录制到cassette
设置模式示例
// 正常模式(默认)
vcr := govcr.NewVCR(
govcr.NewCassetteLoader(exampleCassetteName),
)
// 或
vcr.SetNormalMode()
// 仅实时模式
vcr := govcr.NewVCR(
govcr.NewCassetteLoader(exampleCassetteName),
govcr.WithLiveOnlyMode(),
)
// 或
vcr.SetLiveOnlyMode()
// 只读模式
vcr := govcr.NewVCR(
govcr.NewCassetteLoader(exampleCassetteName),
govcr.WithReadOnlyMode(),
)
// 或
vcr.SetReadOnlyMode(true) // `false`禁用选项
// 离线模式
vcr := govcr.NewVCR(
govcr.NewCassetteLoader(exampleCassetteName),
govcr.WithOfflineMode(),
)
// 或
vcr.SetOfflineMode()
统计信息
VCR提供一些统计信息。要访问统计信息,可以调用vcr.Stats()
,其中vcr是从NewVCR(...)
获得的ControlPanel
实例。
运行测试
make test
govcr是一个功能强大的HTTP请求录制和回放库,可以大大简化测试过程,特别是在需要离线测试或模拟API响应时。通过灵活的配置选项,它可以适应各种测试场景。
更多关于golang实现HTTP请求录制与回放的离线测试插件库govcr的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现HTTP请求录制与回放的离线测试插件库govcr的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用govcr实现HTTP请求录制与回放
govcr是一个Go语言库,用于记录和回放HTTP交互,非常适合离线测试场景。它允许你"录制"真实的HTTP请求和响应,然后在测试中"回放"这些交互,而不需要实际访问远程服务器。
安装govcr
go get github.com/seborama/govcr
基本用法
1. 录制HTTP交互
package main
import (
"fmt"
"net/http"
"github.com/seborama/govcr"
)
func main() {
// 创建一个新的VCR控制器
vcr := govcr.NewVCR(
"my_first_recording", // 录制文件名(不带扩展名)
&govcr.VCRConfig{
Client: &http.Client{}, // 使用标准http.Client
RecordingMode: govcr.RecordingModeRecordOnly,
},
)
// 使用VCR的HTTP客户端
client := vcr.Client
// 发出HTTP请求(会被录制)
resp, err := client.Get("https://jsonplaceholder.typicode.com/posts/1")
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
}
2. 回放录制的交互
package main
import (
"fmt"
"net/http"
"github.com/seborama/govcr"
)
func main() {
// 使用相同的录制文件名,但切换为回放模式
vcr := govcr.NewVCR(
"my_first_recording",
&govcr.VCRConfig{
Client: &http.Client{},
RecordingMode: govcr.RecordingModeReplayOnly,
},
)
// 使用VCR的HTTP客户端
client := vcr.Client
// 发出HTTP请求(会从录制中回放)
resp, err := client.Get("https://jsonplaceholder.typicode.com/posts/1")
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status) // 会输出与录制时相同的响应
}
高级配置
自定义存储位置
vcr := govcr.NewVCR(
"custom_location_recording",
&govcr.VCRConfig{
Client: &http.Client{},
RecordingMode: govcr.RecordingModeRecordOnly,
CassettePath: "./testdata/cassettes", // 自定义存储目录
},
)
混合模式(录制新请求,回放已录制的)
vcr := govcr.NewVCR(
"mixed_mode_recording",
&govcr.VCRConfig{
Client: &http.Client{},
RecordingMode: govcr.RecordingModeNewOnly, // 只录制新请求,回放已存在的
},
)
请求匹配器
默认情况下,govcr会根据Method和URL匹配请求。你可以自定义匹配逻辑:
vcr := govcr.NewVCR(
"custom_matcher",
&govcr.VCRConfig{
Client: &http.Client{},
RecordingMode: govcr.RecordingModeRecordOnly,
RequestMatchers: govcr.RequestMatchers{
// 自定义匹配函数
func(httpRequest, trackRequest *govcr.Request) bool {
// 在这里实现自定义匹配逻辑
return httpRequest.Method == trackRequest.Method &&
httpRequest.URL.String() == trackRequest.URL.String()
},
},
},
)
实际测试示例
package main_test
import (
"net/http"
"testing"
"github.com/seborama/govcr"
"github.com/stretchr/testify/assert"
)
func TestAPI(t *testing.T) {
vcr := govcr.NewVCR(
"api_test",
&govcr.VCRConfig{
Client: &http.Client{},
RecordingMode: govcr.RecordingModeNewOnly,
},
)
t.Run("get post", func(t *testing.T) {
resp, err := vcr.Client.Get("https://jsonplaceholder.typicode.com/posts/1")
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
defer resp.Body.Close()
})
t.Run("create post", func(t *testing.T) {
// 这里可以测试POST请求
})
}
注意事项
- 敏感数据:录制的交互可能包含敏感信息(如API密钥),应考虑加密或手动清理。
- 过期数据:录制的响应可能过时,需要定期更新。
- 动态内容:对于包含时间戳或随机数的响应,可能需要自定义请求匹配器。
- 文件管理:录制文件会累积,应考虑在CI/CD流程中管理它们。
govcr是一个强大的工具,可以显著提高测试的可靠性和速度,特别是在依赖外部API的情况下。通过录制真实的HTTP交互,你可以创建确定性的测试,同时减少对外部服务的依赖。