使用 pytest 动态控制测试顺序

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

我想使用逻辑来控制测试的顺序,当它们已经在运行时,它会动态地重新排序它们。

我的用例是这样的:我使用 xdist 并行化我的测试,每个测试都使用来自公共且有限池的外部资源。有些测试比其他测试使用更多的资源,因此在任何给定时间,当只有一小部分资源可用时,某些测试具有运行所需的资源,而其他测试则没有。

我想优化资源的使用,所以我想根据当前可用的资源动态选择接下来运行哪个测试。我会在收集阶段计算最佳排序,但我事先不知道每个测试需要多长时间,因此我无法预测哪些资源何时可用。

我还没有找到使用插件实现此行为的方法,因为收集阶段似乎与运行阶段不同,并且除了收集挂钩之外,我不知道还有其他方法可以修改要运行的测试列表。

非常感谢任何建议,无论是实现这一点的方法还是优化资源利用的替代想法。我的选择是编写自己的简单测试运行程序,但我不想放弃 pytest 提供的其余功能。

谢谢!

pytest xdist
1个回答
7
投票

并不是您问题的完整答案,而是您关于 pytest 的问题的完整答案,以及一些提示。

要更改 pytest 中测试的顺序(仅 pytest,而不是 pytest-xdist),您可以通过安装此钩子包装器来更改测试项目的顺序:

conftest.py

import pytest
import random

random.seed()

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_protocol(item, nextitem):
    yield

    idx = item.session.items.index(item)
    remaining = item.session.items[idx+1:]
    random.shuffle(remaining)
    item.session.items[idx+1:] = remaining

改变已经执行的内容是没有意义的,而只改变剩下的内容 - 因此,

[idx+1:]
。在此示例中,我只是随机排列项目,但您可以对其余功能列表执行任何您想要的操作。

请记住:这可能会影响灯具的设置和拆卸方式(“功能”上方的范围)。最初,pytest 订购测试,以便他们能够以最有效的方式利用固定装置。具体来说,

nextitem
参数在内部使用来跟踪夹具是否应该完成。由于您每次都有效地更改它,因此效果可能是不可预测的。


使用 pytest-xdist,一切都完全不同。您必须阅读 pytest-dist 如何在从站之间分配测试

首先,每个从属设备都以完全相同的顺序收集所有相同的测试。如果顺序不同,pytest-xdist 将失败。因此您无法在收藏时重新订购它们。

其次,主进程发送收集的列表中的测试索引作为下一个要执行的测试。所以,集合必须始终保持不变。

第三,你可以重新定义

pytest_xdist_make_scheduler
钩子。 pytest-xdist 本身有“很少的示例实现”。您可以使用添加/删除的节点以及通过相应方法收集的测试来定义自己的在 schedule() 方法中安排测试的逻辑。
第四,那太容易了。仅在从从站发送的 

.schedule()

 事件中调用 slave_collectionfinish
 方法。我很遗憾地说,但是您必须始终终止并重新启动从属进程才能触发此事件,并重新安排剩余的测试。
如您所见,pytest-xdist 的实现将非常庞大且复杂。但我希望这能给您一些在哪里查看的提示。

参考资料:

    https://pytest-xdist.readthedocs.io/en/stable/how-it-works.html
© www.soinside.com 2019 - 2024. All rights reserved.