gpt4 book ai didi

python - 如何将参数化 fixture 作为参数传递给另一个 fixture

转载 作者:行者123 更新时间:2023-12-04 15:29:42 25 4
gpt4 key购买 nike

我试图避免在我的测试中重复太多的样板文件,我想以更有条理的方式重写它们。假设我有两个不同的解析器,它们都可以将文本解析为 doc。然后该文档将用于其他测试。最终目标是公开一个可以在其他测试中使用的 doc() 固定装置,并且以运行给定解析器和文本的所有组合的方式进行参数化。

@pytest.fixture
def parser_a():
return "parser_a" # actually a parser object

@pytest.fixture
def parser_b():
return "parser_b" # actually a parser object

@pytest.fixture
def short_text():
return "Lorem ipsum"

@pytest.fixture
def long_text():
return "If I only knew how to bake cookies I could make everyone happy."

现在的问题是,如何创建一个如下所示的 doc() fixture:

@pytest.fixture(params=???)
def doc(parser, text):
return parser.parse(text)

其中 parser 被参数化为 parser_a 和 parser_b,text 被参数化为 short_text 和 long_text。这意味着 doc 总共会测试四种解析器和文本的组合。

有关 PyTest 参数化固定装置的文档非常模糊,我找不到如何解决这个问题的答案。欢迎大家帮忙。

最佳答案

不确定这是否正是您所需要的,但您可以只使用函数而不是固定装置,并将它们组合到固定装置中:

import pytest

class Parser: # dummy parser for testing
def __init__(self, name):
self.name = name

def parse(self, text):
return f'{self.name}({text})'


class ParserFactory: # do not recreate existing parsers
parsers = {}

@classmethod
def instance(cls, name):
if name not in cls.parsers:
cls.parsers[name] = Parser(name)
return cls.parsers[name]

def parser_a():
return ParserFactory.instance("parser_a")

def parser_b():
return ParserFactory.instance("parser_b")

def short_text():
return "Lorem ipsum"

def long_text():
return "If I only knew how to bake cookies I could make everyone happy."


@pytest.fixture(params=[long_text, short_text])
def text(request):
yield request.param

@pytest.fixture(params=[parser_a, parser_b])
def parser(request):
yield request.param

@pytest.fixture
def doc(parser, text):
yield parser().parse(text())

def test_doc(doc):
print(doc)

生成的 pytest 输出是:

============================= test session starts =============================
...
collecting ... collected 4 items

test_combine_fixt.py::test_doc[parser_a-long_text] PASSED [ 25%]parser_a(If I only knew how to bake cookies I could make everyone happy.)

test_combine_fixt.py::test_doc[parser_a-short_text] PASSED [ 50%]parser_a(Lorem ipsum)

test_combine_fixt.py::test_doc[parser_b-long_text] PASSED [ 75%]parser_b(If I only knew how to bake cookies I could make everyone happy.)

test_combine_fixt.py::test_doc[parser_b-short_text] PASSED [100%]parser_b(Lorem ipsum)


============================== 4 passed in 0.05s ==============================

更新:我为解析器添加了一个单例工厂,如评论中所讨论的那样。

注意:我尝试按照@hoefling 的建议使用pytest.lazy_fixture。这行得通,并且可以直接从固定装置传递解析器和文本,但我(还)无法让它以每个解析器只实例化一次的方式工作。作为引用,如果使用 pytest.lazy_fixture,这里是更改后的代码:

@pytest.fixture
def parser_a():
return Parser("parser_a")

@pytest.fixture
def parser_b():
return Parser("parser_b")

@pytest.fixture
def short_text():
return "Lorem ipsum"

@pytest.fixture
def long_text():
return "If I only knew how to bake cookies I could make everyone happy."


@pytest.fixture(params=[pytest.lazy_fixture('long_text'),
pytest.lazy_fixture('short_text')])
def text(request):
yield request.param

@pytest.fixture(params=[pytest.lazy_fixture('parser_a'),
pytest.lazy_fixture('parser_b')])
def parser(request):
yield request.param


@pytest.fixture
def doc(parser, text):
yield parser.parse(text)


def test_doc(doc):
print(doc)

关于python - 如何将参数化 fixture 作为参数传递给另一个 fixture ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61480570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com