繁体   English   中英

Pytest:如何确保首先调用某个灯具

[英]Pytest: How to make sure a certain fixture is called first

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

这里的问题是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添加了一个依赖项,它应该像这样进行参数化:

     @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


可能解决方案

我认为一个可能的解决方案是将辅助函数转换为一个fixture。 所以我可以很容易地在那里添加依赖项,这将依赖于pytest,以及应该执行fixture的顺序。 这看起来像这样:

@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

这将解决我的问题,即文件不存在,但这对我也不起作用,因为它导致我在这里描述的另一个问题: 使用从夹具返回的列表参数化测试

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

不幸的是,你不能从一个夹具中产生多个值,并且你不能通过一个惰性生成器进行参数化。 原因是必须在运行任何灯具或测试之前计算完整的图形,这意味着预先知道所有参数, 如此失败的功能请求中所述 @Hoefling的评论提出了解决这个问题的一种方法。 我建议一种方式可能不那么pytest-thonic,但应该工作。

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

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 ===========================

暂无
暂无

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

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