【问题标题】:pytest leaks attrs objects between testspytest 在测试之间泄漏 attrs 对象
【发布时间】:2019-02-28 12:07:26
【问题描述】:

我正在尝试使用 attr 类的两个不同实例(从函数范围的夹具返回)作为输入参数在 pytest 中运行两个测试。第一个 msg 对象也出现在第二个测试中。我的例子:

import attr
import pytest
import uuid

@attr.s
class Receiver:
    internal_dict = attr.ib(default=dict())

    def send_message(self, msg):
        self.internal_dict[msg] = msg

@pytest.fixture
def msg():
    yield uuid.uuid1()

@pytest.fixture
def receiver():
    yield Receiver()

def test_send_msg_1(msg, receiver):
    receiver.send_message(msg)
    assert len(receiver.internal_dict) == 1

def test_send_msg_2(msg, receiver):
    receiver.send_message(msg)
    print("internal_dict:{}".format(receiver.internal_dict))
    assert len(receiver.internal_dict) == 1  # FAILS

两个测试之间的可变状态如何泄漏?

【问题讨论】:

    标签: python pytest python-attrs


    【解决方案1】:

    此代码共享 same dict() 实例作为可变默认值:

    @attr.s
    class Receiver:
        internal_dict = attr.ib(default=dict())
    

    考虑改为使用工厂:

    @attr.s
    class Receiver:
        internal_dict = attr.ib(factory=dict)
    

    【讨论】:

    • 其实这和pytest无关,和你定义Receiver类的方式有关。即使您的 pytest 固定装置生成了两个不同的实例 Receiver(),它们都共享相同的 internal_dict 属性,因为值 default=dict() 在类定义时被评估一次
    • 所以这个错误可以在没有带有 dict 的 attrs 的情况下重现,在一个定义不佳的 init 中......?
    • 是的,如果您定义了类似def __init__(self, internal_dict={}): self.internal_dict = internal_dict 的初始化函数,则可以在不使用 attr.s 的情况下创建等效的“错误”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2013-03-10
    相关资源
    最近更新 更多