4

使用 pytest-xdist 我运行了一个参数化的测试函数,该函数有一个我感兴趣的变量。我想将变量的值存储在一个单独的对象中,然后使用该对象来编写测试报告。

我尝试使用一个会话范围夹具,它应该在所有测试完成并且结果对象变得可用后立即运行一次。乍一看,它确实工作得很好,但我发现 pytest-xdist没有内置支持来确保会话范围的夹具只执行一次。这意味着我的存储对象很可能从头开始被覆盖 N 次,其中 N 是共享我的测试的 pytest-xdist 工作人员的数量。这不是可取的行为。

一个简短的片段来说明这个问题

# test_x.py

import pytest
from typing import Tuple
from typing import List

@pytest.mark.parametrize('x', list(range(4)))
def test_x(x):
    result = (str(x), x ** 2)  # <-- here I have a dummy result, say a tuple

def write_report(results: List[Tuple[str, int]]):
    # here I would like to have ALL the results that is `results` expected to be:
    # [('0', 0), ('1', 1), ('2', 4), ('3', 9)]
    # considering the fact test_x was paralleled by pytest-xdist to N > 1 workers.
    ...

我运行它pytest -n auto test_x.py

有没有另一种方法来收集result这种顺序多处理测试调用中的所有值?对于此事,我将不胜感激。

Edited

昨天我找到了一个很有前途的 pytest_harvest,但还没有成功。只要不pytest-xdist参与,一切都会顺利。美妙的夹具按预期工作,存储需要的值并在它全部停止时将其results_bag返回到会话结果挂钩中。pytest_sessionfinish但是,当您添加 xdist 工作人员时,突然根本没有会话结果(尽管它确实返回了一个空字典)。

# conftest.py
from pytest_harvest import is_main_process
from pytest_harvest import get_session_results_dct

def pytest_sessionfinish(session):
    dct = get_session_results_dct(session)
    if is_main_process(session):
        print(dct) # prints an empty OrderedDict...

# test_parallel.py
import pytest

@pytest.mark.parametrize('x', list(range(3)))
def test_parallel(x, results_bag):
    results_bag.x = x

pytest -sv test_parallel.py-> 好的

pytest -sv -n auto test_parallel.py-> 一个空的 OrderedDict

任何想法如何使它体面地工作?

4

0 回答 0