我有多个测试需要一个昂贵的生成文件. 我希望在每次测试运行时重新生成该文件,但不要超过一次. 更复杂的是,这些测试和文件都依赖于输入参数.

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

如何确保即使在并行运行这些测试时,该文件也不会跨线程重新生成? 作为背景,我将MakeFiles的测试基础 struct 移植到pytest.

我可以使用基于文件的锁来进行同步,但我相信其他人也遇到过这个问题,他们更愿意使用现有的解决方案.

对于单个线程,使用functools.cache效果很好.带有scope="module"的装置根本不起作用,因为参数input位于函数作用域.

推荐答案

在pytest—xdist文档第"Making session-scoped fixtures execute only once"节中有一个现有的解决方案:

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

请注意,filelock不是标准库的一部分,但可以从PyPI获得.你可以找到documentation here.

Python相关问答推荐

如何将双框框列中的成对变成两个新列

运行总计基于多列pandas的分组和总和

scikit-learn导入无法导入名称METRIC_MAPPING64'

发生异常:TclMessage命令名称无效.!listbox"

log 1 p numpy的意外行为

当从Docker的--env-file参数读取Python中的环境变量时,每个\n都会添加一个\'.如何没有额外的?

cv2.matchTemplate函数匹配失败

有没有一种ONE—LINER的方法给一个框架的每一行一个由整数和字符串组成的唯一id?

使用Python从URL下载Excel文件

如何指定列数据类型

如何使用Numpy. stracards重新编写滚动和?

幂集,其中每个元素可以是正或负""""

基于多个数组的多个条件将值添加到numpy数组

如何在Python中使用Iscolc迭代器实现观察者模式?

如何将泛型类类型与函数返回类型结合使用?

python的文件. truncate()意外地没有截断'

如何训练每一个pandaprame行的线性回归并生成斜率

ValueError:必须在Pandas 中生成聚合值

Pandas:根据相邻行之间的差异过滤数据帧

`Convert_time_zone`函数用于根据为极点中的每一行指定的时区检索值