Как потерпеть неудачу рано (например, установить тайм-аут) на медленных тестах в python3 (желательно с носом)

1

Следующий код воспроизводит мою ситуацию:

from nose.tools import timed
from time import sleep


class Test():
    @timed(1)
    def test_slow_function(self):
        duration = 5
        sleep(duration)
        pass

Запуск теста (например, nosetests test.py:Test -s), я ожидал бы результат отказа всего через 1 секунду. К моему удивлению, это не сработает, пока тест не завершится (в этом случае через 5 секунд). Даже если какой-либо результат через 1 секунду будет неудачным. Я получил:

...
    raise TimeExpired("Time limit (%s) exceeded" % limit)
nose.tools.nontrivial.TimeExpired: Time limit (1) exceeded

----------------------------------------------------------------------
Ran 1 test in 5.006s

FAILED (failures=1)

Я хочу избежать возможности того, что набор тестов никогда не заканчивается (например, при определенных обстоятельствах существует бесконечный цикл). Что было бы хорошим подходом?

Теги:
python-3.x
unit-testing
nose
timeout

1 ответ

1
Лучший ответ

@timed декоратор не может остановить выполнение украшенной функции. Все, что он делает, просто сравнивает реальное время выполнения с ожидаемым, и повышает уровень сбоев, если он превышен.

В основном, чтобы контролировать какой-то процесс и останавливать его в каком-то случае (если он слишком длинный, в вашем примере), вам нужен другой процесс параллельно, который фактически выполняет мониторинг. Легкий и немного хакерский способ, которым вы можете достичь этого, заключается в использовании параллельного тестирования на nose, например:

$ nosetests test.py:Test -s --processes 2 --process-timeout 1
E
======================================================================
ERROR: timesout_nose.Test.test_slow_function
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/test.py", line 9, in test_slow_function
    sleep(duration)
  File "/venv/lib/python3.6/site-packages/nose/plugins/multiprocess.py", line 276, in signalhandler
    raise TimedOutException()
nose.plugins.multiprocess.TimedOutException: 'test.Test.test_slow_function'

----------------------------------------------------------------------
Ran 1 test in 1.230s

FAILED (errors=1)

Вы можете прочитать здесь: http://nose.readthedocs.io/en/latest/plugins/multiprocess.html

Однако вы не сможете настроить простой лимит времени, как это было с декоратором. Но вы все равно можете поймать бесконечные циклы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню