首页 > 解决方案 > 在 Pytest 文档中使用作为 *fruit_bowl 传入参数的目的

问题描述

我正在查看 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 代码不能按原样工作,所以我很难看到如何在我自己的工作中实现对固定装置的使用。

标签: pythonpytest

解决方案


不, * 参数解包根本不是 Pytest 不可或缺的。我会调用 FruitSalad 的参数fruits,去掉 *s。(在声明和调用上)并用注释使其List[Fruit]一目了然。


推荐阅读