gpt4 book ai didi

python - 过滤 pytest 固定装置

转载 作者:行者123 更新时间:2023-12-03 20:49:08 24 4
gpt4 key购买 nike

这与 older question 基本相同但希望现在有更好的解决方案。
问题 :给定一个参数化的 fixture ,如何使用 fixture 对象的子集参数化测试功能?
示例 :

import pytest

@pytest.fixture(params=range(7))
def square(request):
return request.param ** 2

def test_all_squares(square):
sqrt = square ** 0.5
assert sqrt == int(sqrt)

@pytest.fixture()
def odd_square(square):
if square % 2 == 1:
return square
pytest.skip()

def test_all_odd_squares(odd_square):
assert odd_square % 2 == 1
sqrt = odd_square ** 0.5
assert sqrt == int(sqrt)

输出 :
$ pytest pytests.py  -v=================================================================== test session starts ===================================================================...collected 14 items                                                                                                                                        pytests.py::test_all_squares[0] PASSED                                                                                                              [  7%]pytests.py::test_all_squares[1] PASSED                                                                                                              [ 14%]pytests.py::test_all_squares[2] PASSED                                                                                                              [ 21%]pytests.py::test_all_squares[3] PASSED                                                                                                              [ 28%]pytests.py::test_all_squares[4] PASSED                                                                                                              [ 35%]pytests.py::test_all_squares[5] PASSED                                                                                                              [ 42%]pytests.py::test_all_squares[6] PASSED                                                                                                              [ 50%]pytests.py::test_all_odd_squares[0] SKIPPED                                                                                                         [ 57%]pytests.py::test_all_odd_squares[1] PASSED                                                                                                          [ 64%]pytests.py::test_all_odd_squares[2] SKIPPED                                                                                                         [ 71%]pytests.py::test_all_odd_squares[3] PASSED                                                                                                          [ 78%]pytests.py::test_all_odd_squares[4] SKIPPED                                                                                                         [ 85%]pytests.py::test_all_odd_squares[5] PASSED                                                                                                          [ 92%]pytests.py::test_all_odd_squares[6] SKIPPED                                                                                                         [100%]============================================================== 10 passed, 4 skipped in 0.02s ==============================================================

Although this works, it's not ideal:

  • It creates dummy test cases that are always skipped
  • It requires test functions that use the filtered fixture to give a different name (odd_square) to the parameter.

What I'd like instead is e.g. a filter_fixture(predicate, fixture) function that filters the original fixture's objects and can be passed to pytest.mark.parametrize, something like this:

@pytest.mark.parametrize("square", filter_fixture(lambda x: x % 2 == 1, square))
def test_all_odd_squares(square):
assert square % 2 == 1
sqrt = square ** 0.5
assert sqrt == int(sqrt)
这在某种程度上可行吗?

最佳答案

如果您需要一定程度的逻辑来确定将哪些参数应用于每个测试,您可能需要考虑使用 pytest_generate_tests hook.
钩子(Hook)函数pytest_generate_tests为每个收集的测试调用。 metafunc参数允许您动态参数化每个单独的测试用例。重写您的示例以使用 pytest_generate_tests可能看起来像这样:

def pytest_generate_tests(metafunc):
square_parameters = (x**2 for x in range(7))
if 'square' in metafunc.fixturenames:
metafunc.parametrize("square", square_parameters)
if 'odd_square' in metafunc.fixturenames:
odd_square_parameters = (x for x in square_parameters if x % 2 == 1)
metafunc.parametrize("odd_square", odd_square_parameters)

def test_all_squares(square):
sqrt = square ** 0.5
assert sqrt == int(sqrt)

def test_all_odd_squares(odd_square):
assert odd_square % 2 == 1
sqrt = odd_square ** 0.5
assert sqrt == int(sqrt)
这将导致运行以下测试用例:
$ pytest -v pytests.py 
=========== test session starts ===========

collected 10 items

pytests.py::test_all_squares[0] PASSED [ 10%]
pytests.py::test_all_squares[1] PASSED [ 20%]
pytests.py::test_all_squares[4] PASSED [ 30%]
pytests.py::test_all_squares[9] PASSED [ 40%]
pytests.py::test_all_squares[16] PASSED [ 50%]
pytests.py::test_all_squares[25] PASSED [ 60%]
pytests.py::test_all_squares[36] PASSED [ 70%]
pytests.py::test_all_odd_squares[1] PASSED [ 80%]
pytests.py::test_all_odd_squares[9] PASSED [ 90%]
pytests.py::test_all_odd_squares[25] PASSED [100%]

=========== 10 passed in 0.03s ===========
请注意,我的示例中的测试 ID 与您的略有不同。但是,您可以使用 ìds 提供明确的测试标识符。 metafunc.parametrize 的论点.

关于python - 过滤 pytest 固定装置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63780376/

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