Wrapture:将 Python 测试替身与调用追踪结合

Simon Willison8 小时前

Wrapture 是 Graham Dumpleton 推出的 Python 项目,将 wrapt 的运行时补丁(monkey patching)思路扩展到测试与调用追踪两个场景。Dumpleton 此前参与了 wrapt、mod_wsgi 和 New Relic 的 Python 探针等项目。

通过包装函数或方法,Wrapture 可以记录调用,也可以覆盖其返回值。它既提供了替代 unittest.mock 的一种选择,也可用于为已有项目添加追踪能力。

用配置为已有项目添加追踪

Wrapture 支持 OpenTelemetry,并提供完全基于配置的追踪机制。例如:

capture = "summary"

[[observe]]
target = "domain:Calculator"
name = ["outer", "inner"]

[[sink]]
type = "jsonlines"
path = "trace.jsonl"

这段配置指定观察 domain:Calculator 的 outer、inner 方法,并将记录以 JSON Lines 格式写入 trace.jsonl。

两种测试方式:替换返回值与修改实际结果

以下示例中,OrderService().place(...) 会调用 Gateway().charge(...)。代码展示的是测试模式,相关业务类的定义未包含在示例中。

直接替换返回值

使用 on_call.returns(...),可以在上下文中让目标方法返回指定结果:

def test_stub_with_wrapture():
    with wrapture.binding(Gateway, "charge").on_call.returns(
        {"id": "stub", "amount": 0}
    ):
        assert OrderService().place(500)["id"] == "stub"

这里将 Gateway.charge 的返回值替换为固定字典,以验证上层业务代码对该结果的处理。

调用实际方法,再修改返回结果

transforms_result(...) 则允许实际方法先执行,再转换其返回值:

def test_pinned_result_with_wrapture():
    charge = wrapture.binding(Gateway, "charge")
    charge.on_call.transforms_result(
        lambda r: {**r, "id": "ch_TEST"}
    )

    with charge:
        assert OrderService().place(500) == {
            "id": "ch_TEST",
            "amount": 500,
        }

这个测试保留实际返回结果中的其他字段,仅将 id 固定为 ch_TEST。它与直接返回桩数据不同:实际方法仍然会被调用。

AI 编写代码,人负责设计

Dumpleton 表示,Wrapture 的全部代码和文档都由 AI 助手在他的指导下编写,这是他首次尝试大规模、完全由智能体驱动的项目开发。

他强调,这并非一次提示后便直接接受生成结果的做法:项目从一开始就经过工程设计,他凭借相关领域的经验确定目标与设计,AI 则承担具体实现工作。

仍处于早期阶段

介绍时,Wrapture 仅诞生数周。它展示了将测试中的行为替换与运行时观察放在同一套机制下的用法,但现有信息不足以判断其成熟度、性能表现或生产环境适用性。

评论

请登录后发表观点

暂无数据