使用pytest动态控制测试顺序

时间:2017-10-26 11:50:34

标签: pytest xdist

我想使用逻辑来控制测试的顺序,这些逻辑会在运行时对它们进行重新排序。

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

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

我还没有找到一种方法来实现插件的这种行为,因为收集阶段似乎与运行阶段不同,我不知道另一种方法来修改测试列表以运行除集合之外钩。

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

谢谢!

1 个答案:

答案 0 :(得分:5)

对你的问题不是一个完整的答案,而是你对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,一切都完全不同。你必须阅读how pytest-dist distributes the tests across the slaves

首先,每个奴隶都收集所有相同的测试,并且完全按照相同的顺序。如果订单不同,pytest-xdist将失败。所以你不能在收集时重新排序。

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

第三,您可以重新定义pytest_xdist_make_scheduler挂钩。 pytest-xdist本身有few sample implementations。您可以使用添加/删除的节点和通过相应方法收集的测试来定义您自己在schedule()方法中调度测试的逻辑。

第四,那太容易了。只有在从服务器发送的slave_collectionfinish事件中才会调用.schedule()方法。 I' M伤心地说,但你必须杀死并重新启动从处理所有的时间来触发该事件,并重新安排剩下的测试

正如您所看到的,pytest-xdist的实现将是巨大的&复杂。但我希望这会给你一些提示,看看。