py.test с xdist пропускает все тесты с -n > 1
Мои тесты занимают 2 минуты:
$ py.test
================================================= test session starts =================================================
platform linux2 -- Python 2.7.8 -- py-1.4.24 -- pytest-2.5.2
plugins: cov, xdist
collected 2249 items
«lots of file names»
====================================== 2242 passed, 7 skipped in 120.01 seconds =======================================
… Так что я решил попробовать xdist
плагин для запуска их параллельно. Так я и сделал:
$ pip install pytest-xdist
$ py.test -n 2
================================================= test session starts =================================================
platform linux2 -- Python 2.7.8 -- py-1.4.24 -- pytest-2.5.2
plugins: cov, xdist
gw0 [2249] / gw1 [2249]
scheduling tests via LoadScheduling
================================================== in 2.65 seconds ===================================================
2 секунды - это изумительное ускорение... хотя я думаю, что тесты не запускаются - появляются некоторые точки, не так ли? Однако, если я делаю "параллельный" запуск только с одним процессом…
$ py.test -n 1
================================================= test session starts =================================================
platform linux2 -- Python 2.7.8 -- py-1.4.24 -- pytest-2.5.2
plugins: cov, xdist
gw0 [2249]
scheduling tests via LoadScheduling
....«lots and lots of dots»........
====================================== 2242 passed, 7 skipped in 122.27 seconds =======================================
... тогда время пришло в норму.
Как я могу сделать xdist
плагин на самом деле запускает тесты?
ОБНОВИТЬ:
Ответ на вопрос Бруно Оливейра:
$ py.test -n 4 -vv
============================= test session starts ==============================
platform linux2 -- Python 2.7.8 -- py-1.4.24 -- pytest-2.5.2 -- /home/liori/proj/.ve/bin/python2
plugins: cov, xdist
[gw0] linux2 Python 2.7.8 cwd: /home/liori/proj/src
[gw1] linux2 Python 2.7.8 cwd: /home/liori/proj/src
[gw2] linux2 Python 2.7.8 cwd: /home/liori/proj/src
[gw3] linux2 Python 2.7.8 cwd: /home/liori/proj/src
[gw0] Python 2.7.8 (default, Aug 23 2014, 21:00:50) -- [GCC 4.9.1]
[gw1] Python 2.7.8 (default, Aug 23 2014, 21:00:50) -- [GCC 4.9.1]
[gw2] Python 2.7.8 (default, Aug 23 2014, 21:00:50) -- [GCC 4.9.1]
[gw3] Python 2.7.8 (default, Aug 23 2014, 21:00:50) -- [GCC 4.9.1]
gw0 [2254] / gw1 [2254] / gw2 [2254] / gw3 [2254]
scheduling tests via LoadScheduling
=============================== in 4.63 seconds ===============================
2 ответа
Я не использовал рандомизированные значения для параметризации своих тестов, как это было предложено Мареком. Тем не менее, его предложение подтолкнуло меня к проверке другой гипотезы, которая кажется правдой: xdist
требует, чтобы параметризация для тестов генерировалась всегда в одном и том же порядке.
В моем конкретном случае я сгенерировал параметризацию путем итерации по set
струн. Однако эта итерация зависит от конкретных значений, к которым относится хеш строк, и эти значения могут отличаться для каждого процесса. Поэтому, хотя я всегда генерировал одни и те же параметризации, они были в другом порядке.
Простой тестовый пример, который показывает проблему:
import pytest
my_names = {'john', 'kate', 'alfred', 'paul', 'mary'}
@pytest.mark.parametrize('name', list(my_names), ids=list(my_names))
def test_is_name_short(name):
assert len(name) < 7
Бежать с PYTHONHASHSEED=random py.test -n 4
чтобы убедиться, что вы запускаете случайное хеширование для строк.
Простой обходной путь заключается в применении определенного порядка в тестах, например, путем сортировки их по некоторому параметру:
my_names = sorted(my_names)
Я отправил на багтрекер py.test предложение сделать xdist
сортировать параметризации для сравнения, чтобы избежать этой проблемы.
По мне похоже на подобную проблему я заметил:)
Ваши тесты как-то случайно параметризованы? Если да, пожалуйста, посмотрите, что py.test с xdist не выполняет тесты, параметризованные случайными значениями
И в Твоем, и в моем случае оно фактически не пропускается (если оно действительно пропущено, то в резюме Вы пропустили бы X)