为什么pytest-xdist让我的测试运行得更慢,而不是更快?

时间:2017-02-17 02:08:16

标签: pytest pytest-django

我正在将{2000}方法测试套件从nose移植到pytest,因为django-nose不能很好地支持并行化。更换pytest的鼻子似乎工作得很好,并且在python_files添加pytest.ini后,它几乎发现了我们所有的测试。

最大的缺点是,当我使用-n 4运行时,测试套件变得比没有-n标志的情况慢。在整个套件的~10%子集上运行,看起来大约有20-30%的减速,尽管我采取的时间相当嘈杂。这有点像开销,但无论我选择多少个进程,时间都不会下降。

使用--durations=20运行显示每个设置阶段每个进程需要几秒钟的时间,而另一个测试的速度稍慢。

使用-vvv列出运行时的测试,输出几乎完全序列化:

api/tests/VERSION_NUMBER.py::ATestCase::test_forbidden_methods <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_access_token <- api/testcases.py
api/tests/VERSION_NUMBER.py::ATestCase::test_create <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_create <- api/testcases.py
api/tests/VERSION_NUMBER.py::ATestCase::test_delete <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_delete <- api/testcases.py
api/tests/VERSION_NUMBER.py::ATestCase::test_patch <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_patch <- api/testcases.py
api/tests/VERSION_NUMBER.py::ATestCase::test_put <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_put <- api/testcases.py
api/tests/VERSION_NUMBER.py::ATestCase::test_retrieve <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_retrieve <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_access_token <- api/testcases.py
[gw0] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_forbidden_methods <- api/testcases.py
api/tests/VERSION_NUMBER.py::ATestCase::test_list <- api/testcases.py
[gw0] PASSED api/tests/VERSION_NUMBER.py::ATestCase::test_list <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_delete <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_access_token <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_create <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_create <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_list <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_list <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_patch <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_patch <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_put <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_put <- api/testcases.py
[gw0] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_delete <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_forbidden_methods <- api/testcases.py
api/tests/VERSION_NUMBER.py::BTestCase::test_retrieve <- api/testcases.py
[gw0] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_forbidden_methods <- api/testcases.py
[gw1] PASSED api/tests/VERSION_NUMBER.py::BTestCase::test_retrieve <- api/testcases.py

除了少数例外,它几乎总是“开始测试,从工人那里获得通过”以获得整个日志。这让我相信某些东西正在序列化测试,但我对于什么感到困惑。

我已经尝试禁用除pytest本身,pytest-xdist和pytest-django之外的所有pytest插件,没有任何变化。

3 个答案:

答案 0 :(得分:1)

阅读https://github.com/pytest-dev/pytest-xdist/blob/master/OVERVIEW.md,您将猜测为什么在某些情况下它会变慢。

并行化时可能会变慢:

  • 总的测试持续时间非常慢(不到2分钟)-启动pytest工作者会增加额外的时间,如果那比收益还长...
  • 您的测试已经占用了磁盘或网络等共享的有限资源,因此并行运行可能会使速度变慢

答案 1 :(得分:0)

确保正确控制测试并行性的使用方式,按照Is there a way to control how pytest-xdist runs tests in parallel?上的答案验证您是否正确使用参数,尤其要注意 dist 参数的设置方式。我建议将其设置为 --dist=loadfile

答案 2 :(得分:0)

如果您的测试还不是很长,那么使用 xdist 很容易导致运行时间比使用串行慢,这在 https://github.com/pytest-dev/pytest-xdist/issues/346 上是已知和记录的

AFAIK,没有明确的解决方案,应该由您决定哪个项目从 xdist 中受益,或者调整工作人员的数量以优化结果。