
测试开发工具【免费下载链接】vcrRecord your test suites HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.项目地址https://gitcode.com/gh_mirrors/vc/vcr点击查看免费下载导读本文讲解 VCRgh_mirrors/vc/vcr仓库中:decode_compressed_response这个 cassette 选项当它被设为真值时VCR 会在录制阶段自动解压 gzip 与 deflate 编码的响应体使录制下来的 HTTP 交互在序列化后变得可读、可编辑。读完本文你将掌握该选项的用法、默认行为、底层解压实现原理以及它与:preserve_exact_body_bytes、:recompress_response等相邻选项的取舍关系。选项是什么:decode_compressed_response是VCR.use_cassette以及insert_cassette接受的合法选项之一。根据 lib/vcr.rb 中的 API 文档其语义为Whether or not to decode compressed responses before recording the cassette. This makes the cassette more human readable. Defaults to false.即在录制 cassette 之前解码压缩响应让 cassette 更易读默认值为false。从 lib/vcr/cassette.rb 的assert_valid_options!方法可以看到decode_compressed_response与:update_content_length_header、:preserve_exact_body_bytes、:recompress_response等并列属于合法的 cassette 选项白名单传入拼写错误的选项会抛出ArgumentError。默认行为不解压保留原始编码默认情况下该选项未开启VCR 把响应体原样序列化进 cassette 文件。仓库中的验收场景见 features/cassettes/decompress.feature 与配套文档 docs/cassettes/decompress.md用一段 Sinatra 应用验证了这一行为服务器把文本The quick brown fox jumps over the lazy dog用Zlib::GzipWriter压缩后在响应头设置Content-Encoding: gzip返回。准备脚本decompress.rbrequire zlib require stringio $server start_sinatra_app do get(/) { content The quick brown fox jumps over the lazy dog io StringIO.new writer Zlib::GzipWriter.new(io) writer content writer.close headers[Content-Encoding] gzip io.string } end require vcr VCR.configure do |c| c.cassette_library_dir cassettes c.hook_into :webmock c.default_cassette_options { serialize_with: :syck } end随后不开启任何解压选项发起请求VCR.use_cassette(:decompress) do Net::HTTP.start(localhost, $server.port) do |http| http.get(/, accept-encoding identity) end end运行ruby decompress.rb后生成的cassettes/decompress.yml中会保留Content-Encoding: - gzip也就是说响应头与压缩后的二进制 body 被原样记录。这样的 cassette 里是一段不可读的压缩字节手工编辑或 diff 都很困难。开启选项录制前先解压把选项设为真值再运行一次VCR.use_cassette(:decompress, decode_compressed_response: true) do Net::HTTP.start(localhost, $server.port) do |http| http.get(/, accept-encoding identity) end end再次执行ruby decompress.rb此时cassettes/decompress.yml中Content-Encoding头已消失取而代之的是Content-Length: - 43并且 body 变为明文string: The quick brown fox jumps over the lazy dog对比默认行为与开启后的结果可以清晰看到该选项带来的三个可观察效果body 被解压gzip 字节流变成可读的纯文本Content-Encoding响应头被删除因为 body 已不再是压缩编码Content-Length被同步更新解压后的 body 长度为 43 字节VCR 会重写该头部保证 replay 时响应自洽。底层实现一个内置的 before_record 钩子该选项本质上不是一个独立的解压分支而是 VCR 内置钩子built-in hooks的一种简洁封装。在 lib/vcr/configuration.rb 的register_built_in_hooks中可以看到before_record(:decode_compressed_response) do |interaction| interaction.response.decompress if interaction.response.compressed? end也就是说decode_compressed_response会被当作一个cassette tag注册到内置钩子上lib/vcr/cassette.rb 中assign_tags会把真值选项加入tags从而在before_record阶段对每条交互执行response.decompress。decompress与compressed?的实现位于 lib/vcr/structs.rbdef content_encoding enc get_header(Content-Encoding) and enc.first end def compressed? %w[ gzip deflate ].include? content_encoding end def decompress self.class.decompress(body, content_encoding) { |new_body| self.body new_body update_content_length_header adapter_metadata[vcr_decompressed] content_encoding delete_header(Content-Encoding) } return self end关键细节仅识别gzip和deflate其他编码如br、zstd不会被compressed?判定为压缩也就不会被自动解压。解压后记录元数据adapter_metadata[vcr_decompressed]记下原始编码同时调用update_content_length_header重算长度、delete_header(Content-Encoding)删除编码头对应 lib/vcr/structs.rb 的实现。实际解码动作由类方法self.decompress完成lib/vcr/structs.rbdef self.decompress(body, type) unless HAVE_ZLIB warn VCR: cannot decompress response; Zlib not available return end case type when gzip yield Zlib::GzipReader.new(StringIO.new(body), encoding: ASCII-8BIT).read when deflate yield Zlib::Inflate.inflate(body) when identity, NilClass return else raise Errors::UnknownContentEncodingError, unknown content encoding: #{type} end end这里有两个值得注意的工程细节依赖 Zlib文件顶部有require zlib/require stringio的守卫lib/vcr/structs.rb若当前 Ruby 环境没有 ZlibVCR 只打印警告并跳过解压而不是让测试直接失败。未知编码抛错遇到无法识别的编码会抛出VCR::Errors::UnknownContentEncodingError定义于 lib/vcr/errors.rb。与相邻选项的配合与取舍何时应该关闭该选项官方文档明确提醒见 docs/cassettes/decompress.mdThis option should be avoided if the actual decompression of response bodies is part of the functionality of the library or app being tested.如果被测代码本身就实现了 gzip/deflate 解压逻辑例如你在测试一个 HTTP 客户端库的自动解压能力那么录制前替它解压会破坏测试的真实性。这种情况下应保持默认不开启或改用:preserve_exact_body_bytes见 lib/vcr.rb以 base64 形式完整保留原始字节。配合:recompress_response保证 replay 语义解压录制之后cassette 中的响应已经失去Content-Encoding头replay 时客户端拿到的也是明文。如果你需要 playback 阶段恢复压缩语义可以组合使用:recompress_response选项其内置钩子为lib/vcr/configuration.rbrecompress_response(tag_filter_from(:recompress_response)) do |interaction| interaction.response.recompress if interaction.response.vcr_decompressed? end该钩子在before_playback阶段lib/vcr/cassette.rb 中的invoke_hook(:recompress_response, interactions)依据adapter_metadata[vcr_decompressed]记录的原始编码用Zlib::GzipWriter或Zlib::Deflate.inflate重新压缩 body 并恢复Content-Encoding头lib/vcr/structs.rb。这样录制时解压便于阅读、回放时重新压缩保持语义就形成了一个完整闭环。与其他配置的组合使用该选项既可以在use_cassette时按次传入也可以通过default_cassette_options全局开启例如VCR.configure do |c| c.default_cassette_options { decode_compressed_response: true, serialize_with: :syck } enddefault_cassette_options的合并逻辑见 lib/vcr/configuration.rb默认值集合中并不包含该选项lib/vcr/configuration.rb因此未显式设置时行为与false一致。小结行为默认未开启decode_compressed_response: truebody 录制内容原始 gzip/deflate 压缩字节解压后的明文Content-Encoding头保留删除Content-Length原样按解压后长度重写适用场景被测代码自身负责解压需要 cassette 可读、可编辑、可 diff:decode_compressed_response是 VCR 提升 cassette 可读性的重要开关它通过内置before_record钩子对gzip/deflate响应做解压、删除编码头并同步Content-Length让录制结果成为干净、可直接编辑的文本但若解压本身是被测对象的功能则应保持默认关闭。需要回放时恢复压缩语义可再叠加:recompress_response选项。赞分享测试开发工具【免费下载链接】vcrRecord your test suites HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.项目地址https://gitcode.com/gh_mirrors/vc/vcr点击查看免费下载相关推荐DataHub TiDB 元数据接入指南基于 MySQL 兼容路径的 TiDB Source 完整实践DataHub TiDB 元数据接入指南基于 MySQL 兼容路径的 TiDB Source 完整实践 导读 TiDB Source 是 DataHub 元数测试开发工具3分钟快速上手drawio-desktop开源流程图工具完整指南3分钟快速上手drawio desktop开源流程图工具完整指南 还在为复杂的流程图工具烦恼吗 每次打开浏览器才能画图担心数据安全或者被各种付费订阅桌面应用图形学规范驱动开发策略利用Spec Kit实现软件工程流程自动化规范驱动开发策略利用Spec Kit实现软件工程流程自动化 在传统软件开发中团队往往面临规范文档与代码实现脱节、需求变更难以追踪、开发流程缺乏标准化等核心痛开发工具CLI工作流自动化上一篇macOS效率工具2024黑五特惠Black Friday Deals剪贴板管理软件推荐下一篇dbskill 微信公众号 HTML 生成实战Markdown 转微信后台粘贴版 HTML 的兼容性规则与 15 种风格库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考