You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Hypothesis状态测试中使用Syrupy创建并对比快照?

在Hypothesis状态测试中使用Syrupy快照

因为Hypothesis的RuleBasedStateMachine不支持pytest夹具,没法直接用Syrupy的snapshot夹具,核心解决思路是手动初始化Syrupy的SnapshotAssertion实例,绕过夹具限制,同时保留快照对比/更新的功能。

核心实现步骤

  1. 手动初始化Syrupy快照:在状态机类的初始化方法里创建SnapshotAssertion实例,指定快照存储路径和更新逻辑。
  2. 统一更新控制:通过pytest命令行参数--snapshot-update控制快照的更新/对比模式,和常规Syrupy用法保持一致。
  3. 唯一快照标识:状态机生成的测试序列是动态的,要给每个快照设置唯一名称(比如动作序列、状态阶段),避免不同用例的快照相互覆盖。

完整代码示例

首先安装依赖:

pip install hypothesis syrupy

测试文件test_state_machine.py:

from hypothesis.stateful import RuleBasedStateMachine, rule, initialize
from syrupy.extensions.single_file import SingleFileSnapshotExtension
from syrupy import SnapshotAssertion
import pytest

class ExampleStateMachine(RuleBasedStateMachine):
    def __init__(self):
        super().__init__()
        # 手动初始化Syrupy快照
        self.snapshot = SnapshotAssertion(
            extension=SingleFileSnapshotExtension,
            test_location=__file__,  # 以当前测试文件为快照定位基准
            update_snapshots=pytest.config.getoption("--snapshot-update", default=False)
        )
        self.data = []
        self.action_log = []  # 记录动作序列,用于生成唯一快照ID

    @initialize
    def setup_initial_state(self):
        self.data = []
        self.action_log = []

    @rule(value=int)
    def add_value(self, value):
        self.data.append(value)
        self.action_log.append(f"add({value})")
        # 用动作序列作为快照名称,确保每个测试序列的快照唯一
        snapshot_id = "_".join(self.action_log)
        self.snapshot.assert_match(self.data, name=snapshot_id)

    @rule()
    def verify_final_state(self):
        # 对最终状态单独生成快照
        final_snapshot_id = "final_state_" + "_".join(self.action_log)
        self.snapshot.assert_match(self.data, name=final_snapshot_id)

# 生成测试用例类,设置固定seed保证测试确定性
TestExampleStateMachine = ExampleStateMachine.TestCase.with_settings(seed=12345)

运行方式

  • 首次运行/更新快照:生成或更新快照文件
    pytest test_state_machine.py --snapshot-update
    
  • 常规快照对比:自动对比现有快照,检查状态变更是否符合预期
    pytest test_state_machine.py
    

关键注意事项

  • 固定Hypothesis的seed参数可以保证测试序列的确定性,避免每次运行生成不同的快照。
  • 快照名称必须唯一,否则不同的测试序列会覆盖同一个快照文件,导致断言失败。
  • 不需要每个动作都做快照时,可以只在关键节点(比如初始化后、最终状态)进行快照断言。

内容的提问来源于stack exchange,提问作者Yang Bo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:35:05