17

我正在将一个 ~2000 方法测试套件从鼻子移植到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 插件,没有任何变化。

4

3 回答 3

2

阅读https://github.com/pytest-dev/pytest-xdist/blob/master/OVERVIEW.md,你会猜到为什么在特定情况下它会慢很多。

并行化时可能会更慢:

  • 总测试持续时间很慢(不到 2 分钟) - 引导 pytest 工作人员会增加额外的时间,如果这大于好处......
  • 您的测试已经占用了磁盘或网络等共享有限资源,因此并行运行可能会使其变慢
于 2020-08-30T07:09:46.490 回答
0

确保您正确控制了使用测试并行性的方式,按照Is there a way to control how pytest-xdist 如何并行运行测试的答案?验证您是否正确使用参数,特别注意 dist 参数的设置方式。我建议设置它--dist=loadfile

于 2021-01-17T10:59:46.540 回答
0

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

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

于 2021-07-07T08:40:55.870 回答