pytest、xdist 和共享生成的文件依赖项

问题描述 投票:0回答:1

我有多个测试需要昂贵的生成文件。 我希望在每次测试运行时重新生成该文件,但最多一次。 让事情变得复杂的是,这些测试以及文件都依赖于输入参数。

def expensive(param) -> Path:
    # Generate file and return its path.

@mark.parametrize('input', TEST_DATA)
class TestClass:

    def test_one(self, input) -> None:
        check_expensive1(expensive(input))

    def test_two(self, input) -> None:
        check_expensive2(expensive(input))

如何确保即使并行运行这些测试,该文件也不会跨线程重新生成? 对于上下文,我将 Makefile 的测试基础设施移植到 pytest。

我可以使用基于文件的锁进行同步,但我确信其他人也遇到过这个问题,并且宁愿使用现有的解决方案。

使用

functools.cache
对于单线程非常有效。带有
scope="module"
的夹具根本不起作用,因为参数
input
位于函数范围内。

python pytest pytest-xdist
1个回答
0
投票

pytest-xdist 文档部分中有一个现有的解决方案“使会话范围的装置仅执行一次”

import json

import pytest
from filelock import FileLock


@pytest.fixture(scope="session")
def session_data(tmp_path_factory, worker_id):
    if worker_id == "master":
        # not executing in with multiple workers, just produce the data and let
        # pytest's fixture caching do its job
        return produce_expensive_data()

    # get the temp directory shared by all workers
    root_tmp_dir = tmp_path_factory.getbasetemp().parent

    fn = root_tmp_dir / "data.json"
    with FileLock(str(fn) + ".lock"):
        if fn.is_file():
            data = json.loads(fn.read_text())
        else:
            data = produce_expensive_data()
            fn.write_text(json.dumps(data))
    return data
© www.soinside.com 2019 - 2024. All rights reserved.