我正在浏览pytest文档,有一个小细节让我抓狂。
我正在看这个页面的文档,它给出了下面的例子:
import pytest
class Fruit:
def __init__(self, name):
self.name = name
self.cubed = False
def cube(self):
self.cubed = True
class FruitSalad:
def __init__(self, *fruit_bowl):
self.fruit = fruit_bowl
self._cube_fruit()
def _cube_fruit(self):
for fruit in self.fruit:
fruit.cube()
# Arrange
@pytest.fixture
def fruit_bowl():
return [Fruit("apple"), Fruit("banana")]
def test_fruit_salad(fruit_bowl):
# Act
fruit_salad = FruitSalad(*fruit_bowl)
# Assert
assert all(fruit.cubed for fruit in fruit_salad.fruit)
我得到了本页上发生的事情的基本概念,但是在fruit_bowl
参数中包含*
让我感到困惑。
例如,如果您只想自己初始化类,代码将无法工作:
fruit_bowl = [Fruit("Apple"), Fruit("Banana")]
fruit_salad = FruitSalad(fruit_bowl)
返回错误消息:
AttributeError: 'list' object has no attribute 'cube'
在这种情况下,将*fruit_bowl
参数替换为fruit_bowl
就可以了。
然后我意识到fruit_bowl
被定义为一个函数,所以我认为这将会奏效,但是再次只是在测试之外运行代码返回一个错误。
def fruit_bowl():
return [Fruit("Apple"), Fruit("Banana")]
class Fruit():
def __init__(self, name):
self.name = name
self.cubed = False
def cube(self):
self.cubed = True
class FruitSalad():
def __init__(self, *fruit_bowl):
self.fruit_bowl = fruit_bowl
self._cube_fruit()
def _cube_fruit(self):
for fruit in self.fruit_bowl:
fruit.cube()
然后运行fruit_salad = FruitSalad(fruit_bowl)
给出错误信息AttributeError: 'function' object has no attribute 'cube'
。
这是否意味着*fruit_bowl
参数的使用特定于pytest的工作方式?也就是说,只有当参数是一个添加了@fixture
装饰器的函数时,这些东西才会起作用,或者还有其他一些我遗漏的点。
目前,我发现列出的代码令人困惑,因为非pytest代码不能按原来的方式工作,所以我很难看到如何在我自己的工作中实现fixture的使用。
不,*参数unpacking根本不是Pytest的组成部分。我把这个论点称为水果沙拉fruits
,去掉*。(声明和调用),并使用List[Fruit]
注释,使其清晰。