简体   繁体   English

Pytest 使用夹具参数化测试

[英]Pytest parametrize a test using a fixture

I am trying to better understand how to thoroughly unit test using pytest and came across a situation that I am not sure how to best approach.我试图更好地了解如何使用pytest进行彻底的单元测试,但遇到了一种我不确定如何最好的方法的情况。 I found similar questions here on SO about parameterizing fixtures themselves but I don't think that is what I want to do here.我在 SO 上发现了类似的关于参数化装置本身的问题,但我认为这不是我想要在这里做的。 But maybe I am not fully understanding fixtures themselves?但也许我并没有完全理解灯具本身?

Here is some sample code:下面是一些示例代码:

App Code:应用程序代码:

class Person:
    def __init__(self, fname: str, lname: str):
        self.fname = fname
        self.lname = lname

    def upper_fullname(self):
        return f'{self.fname} {self.lname}'.upper()

Tests:测试:

import pytest

@pytest.fixture(scope="module")
def fixture_mm(conf={"fname": "mickey", "lname": "mouse"}):
    return Person(**conf)

@pytest.fixture(scope="module")
def fixture_bb(conf={"fname": "bugs", "lname": "bunny"}):
    return Person(**conf)

@pytest.mark.parametrize(
    'person, expected_result',
    [(fixture_mm, "MICKEY MOUSE"), (fixture_bb, "BUGS BUNNY")])
def test_uppernames(person, expected_result):
    assert person.upper_fullname() == expected_result

I would expect both of these tests to pass but instead I get an error message saying AttributeError: 'function' object has no attribute 'upper_fullname' .我希望这两个测试都能通过,但我收到一条错误消息,指出AttributeError: 'function' object has no attribute 'upper_fullname' What am I missing here?我在这里缺少什么?

Thanks.谢谢。

You're getting an error because fixture_mm is a function.您收到错误,因为fixture_mm是一个函数。 You need to call a function to get a value ( fixture_mm() ), but this is not going to work with fixtures.您需要调用一个函数来获取一个值( fixture_mm() ),但这不适用于夹具。

But I don't think you even need fixtures here.但我认为你在这里甚至不需要固定装置。 You could make these into normal functions and use them like this:你可以把它们变成普通函数并像这样使用它们:

def person_mm(conf={"fname": "mickey", "lname": "mouse"}):
    return Person(**conf)

def person_bb(conf={"fname": "bugs", "lname": "bunny"}):
    return Person(**conf)

@pytest.mark.parametrize(
    'person, expected_result',
    [(person_mm(), "MICKEY MOUSE"), (person_bb(), "BUGS BUNNY")])
def test_uppernames(person, expected_result):
    assert person.upper_fullname() == expected_result

Caveat: since fixture parameters are evaluated at the module compile time, this might cause issues if the functions require some setup.警告:由于在模块编译时评估夹具参数,如果函数需要一些设置,这可能会导致问题。 On the other hand, if your functions are as simple as in this example, you could even save these objects as constants:另一方面,如果你的函数像这个例子一样简单,你甚至可以将这些对象保存为常量:

PERSON_MM = Person(fname="mickey", lname="mouse")
PERSON_BB = Person(fname="bugs", lname="bunny")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM