目标:我需要在测试收集之前在 pytest 缓存中设置一些随机值。
问题:如果我使用带有选项 master 的 pytest-xdist 并行运行测试,--cache-clear
并且每个工作人员都会清除缓存,所以我需要确保所有工作人员在设置值之前都准备好。
可能的解决方案:
def pytest_configure(config):
if (
hasattr(config, "workerinput")
and "--cache-clear" in config.invocation_params.args
):
# if it's worker of parallel run with cache clearing,
# need to wait to make sure that all workers are started.
# Otherwise, the next started worker will clear cache and create
# a new organization name
time.sleep(10)
name = config.cache.get(CACHE_ORG_KEY, None)
if not name:
name = <set random value>
config.cache.set(CACHE_ORG_KEY, name)
它工作正常。我有 10 秒的睡眠时间,似乎足以启动所有工作人员(节点)。所有工作人员都已启动,所有工作人员都清除缓存。第一个将值设置为缓存,其他人获取它。但我不喜欢这种方法,因为不能保证所有的工人都启动+额外的等待时间。
我考虑其他方法:
- 禁用清除工作人员的缓存
- 检查所有工作人员是否已启动
但我不知道该怎么做。有任何想法吗?
UPD #1。最小的可重现示例
要求:
pytest==6.2.5
pytest-xdist==2.5.0
代码:
conftest.py
import time
from test_clear_cache import set_name
def pytest_configure(config):
# if (
# hasattr(config, "workerinput")
# and "--cache-clear" in config.invocation_params.args
# ):
# time.sleep(10)
name = config.cache.get("name", None)
if not name:
name = f"name_{time.time_ns()}"
config.cache.set("name", name)
set_name(name)
test_clear_cache.py
import sys
NAME = "default"
def set_name(name):
global NAME
NAME = name
def test_clear_cache1():
print(f"Test #1: {NAME}", file=sys.stderr)
def test_clear_cache2():
print(f"Test #2: {NAME}", file=sys.stderr)
def test_clear_cache3():
print(f"Test #3: {NAME}", file=sys.stderr)
def test_clear_cache4():
print(f"Test #4: {NAME}", file=sys.stderr)
输出:
(venv) C:\Users\HP\PycharmProjects\PytestCacheClear>pytest -s -n=4 --cache-clear
========================================================================================================== test session starts ===========================================================================================================
platform win32 -- Python 3.7.8, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: C:\Users\HP\PycharmProjects\PytestCacheClear
plugins: forked-1.4.0, xdist-2.5.0
gw0 [4] / gw1 [4] / gw2 [4] / gw3 [4]
Test #4: name_1643377905887805600
Test #3: name_1643377905816748300
Test #2: name_1643377905735875700
Test #1: name_1643377905645880100
....
=========================================================================================================== 4 passed in 0.61s ============================================================================================================
注意:如果您在conftest.py
测试中取消注释代码将打印相同的名称。