gpt4 book ai didi

python - Pytest:如何确保首先调用某个固定装置

转载 作者:行者123 更新时间:2023-11-28 17:03:27 26 4
gpt4 key购买 nike

我在 a_file 中有一些数据,我需要用它来参数化我的 fixture 。因此,我编写了一个辅助函数,它返回用文件中的数据填充的 a_list。现在我可以通过 @pytest.fixture(params=a_list) 轻松地参数化我的 fixture 。看起来很简单,对吧?

这里的问题是 a_file 是由另一个 fixture 生成的,似乎 pytest 在 fixture 实际创建文件之前调用了依赖于该文件的 helper。由于该行为,引发了 FileNotFoundError

我的代码是这样的:

def helper_returning_list_from_a_file():
with open("a_file") as a_file:
a_list = a_file.readlines()

return a_list

@pytest.fixture(scope="session")
def create_file_fixture(depends_on_other_fixtures):
# create "a_file" here

@pytest.fixture(params=helper_returning_list_from_a_file())
def a_fixture_which_is_parametrized_with_data_from_a_file(request):
return request.param

def test_which_uses(a_fixture_which_is_parametrized_with_data_from_a_file):
assert False

补充:create_file_fixture需要是一个fixture,不能转化为普通函数,因为它依赖于其他fixture。


我已经尝试过的

显而易见的解决方案是确保在需要文件的辅助函数执行之前创建文件。

所以我

  • create_file_fixture 的依赖项添加到应该像这样参数化的 fixture :

    @pytest.fixture(params=helper_returning_list_from_a_file())
    def a_fixture_which_is_parametrized_with_data_from_a_file(create_file_fixture, request):
    return request.param
  • autouse 标志添加到创建文件的 fixture,如下所示:

    @pytest.fixture(scope="session", autouse=True)
    def create_file_fixture:
    # create "a_file" here

但 pytest 仍然首先调用辅助函数,这会导致与上述相同的错误。


问题

如何确保首先执行 create_file_fixture


可能的解决方案

我认为一个可能的解决方案是将辅助函数也转换为固定装置。所以我可以很容易地在那里添加依赖项,它会指示 pytest 应该按照哪个顺序执行固定装置。这看起来像这样:

@pytest.fixture()
def fixture_returning_list_from_a_file(create_file_fixture):
with open("a_file") as a_file:
a_list = a_file.readlines()

return a_list

这将解决我的文件不存在的问题,但这对我也不起作用,因为它会导致我在此处描述的另一个问题:parametrizing a test with a list returned from a fixture .

最佳答案

错误不是由 pytest 本身引起的。这是因为当模块被 Python 解释器加载时,名义上是在它到达 pytest 之前,你的辅助函数被调用。

不幸的是,您不能从一个 fixture 中产生多个值,也不能对惰性生成器进行参数化。原因是必须在运行任何固定装置或测试之前计算完整的图形,这意味着预先知道所有参数,如 this failed feature request 中所述。 . @Hoefling's comment建议一种解决此问题的方法。我会建议一种可能不那么 pytest-thonic,但应该仍然有效的方法。

为确保您的文件是预先创建的并且整个列表可用于参数化,请不要将其设为 fixture :只需将其作为模块加载代码的一部分运行并将列表设为模块属性即可。这不会阻止您在其他地方使用它。如果多个测试模块使用同一个列表,您可以将它放入一个单独的非测试模块中,然后将其导入到需要它的测试中。

def create_file_function():
# create "a_file" here
return 'a_file'

def helper_returning_list_from_a_file():
with open(create_file_function()) as a_file:
a_list = a_file.readlines()

return a_list

a_list = helper_returning_list_from_a_file()

@pytest.fixture(params=a_list)
def a_fixture_which_is_parametrized_with_data_from_a_file(request):
return request.param

def test_which_uses(a_fixture_which_is_parametrized_with_data_from_a_file):
assert False

我认为让 create_file_function 返回文件名更优雅/可配置。

给定的 a_file 看起来像:

ABC
DEF

pytest -v 的输出如下所示:

============================= test session starts ==============================
platform linux -- Python 3.6.4, pytest-3.4.2, py-1.5.2, pluggy-0.6.0 -- /...
cachedir: .pytest_cache
rootdir: /..., inifile:
plugins: remotedata-0.2.0, pep8-1.0.6, openfiles-0.2.0, doctestplus-0.1.2, arraydiff-0.2
collected 2 items

52765085.py::test_which_uses[ABC\n] PASSED [ 50%]
52765085.py::test_which_uses[DEF] PASSED [100%]

=========================== 2 passed in 0.01 seconds ===========================

关于python - Pytest:如何确保首先调用某个固定装置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52765085/

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