Как использовать pdb.set_trace() в Django unittest?
Я хочу отлаживать Django TestCase так же, как и любой другой код Python: просто позвоните pdb.set_trace()
, а затем перейдите в интерактивный сеанс. Когда я это делаю, я ничего не вижу, поскольку тесты выполняются в другом процессе. Я использую django-discover-runner, но я предполагаю, что это относится к тестовому бегунгу Django по умолчанию.
Вопрос:
Можно ли зайти в сеанс pdb
при использовании django-discover-runner
a) при каждой ошибке/сбое, AND/ИЛИ b) только тогда, когда я вызываю pdb.set_trace()
в своем тестовом коде?
Некоторые исследования:
Этот ответ объясняет, что Django создает другой процесс и предлагает использовать вызов rpdb2 debugger
, часть winpdb
, но я не хочу используйте winpdb
, я бы предпочел использовать ipdb
.
Этот ответ решает проблему для django-nose
, запустив тестовую команду следующим образом: ./manage.py test -- -s
, но эта опция недоступна для django-discover-runner
.
Этот ответ показывает, что я могу сделать это с помощью ipython
:
In [9]: %pdb
Automatic pdb calling has been turned ON
Это похоже на потенциальный вариант, но кажутся немного громоздкими для запуска ipython
при каждом запуске тестов.
Наконец, этот ответ показывает, что nose
поставляется с флагом --pdb
, который падает на pdb
на ошибках, чего я хочу. Является ли единственным вариантом для переключения на тестовый бегун django-nose
?
Я не вижу никаких параметров для этого во встроенной справке для django-discover-runner
:
$ python manage.py help test --settings=settings.test
Usage: manage.py test [options] [appname ...]
Runs the test suite for the specified applications, or the entire site if no apps are specified.
Options:
-v VERBOSITY, --verbosity=VERBOSITY
Verbosity level; 0=minimal output, 1=normal output,
2=verbose output, 3=very verbose output
--settings=SETTINGS The Python path to a settings module, e.g.
"myproject.settings.main". If this isn't provided, the
DJANGO_SETTINGS_MODULE environment variable will be
used.
--pythonpath=PYTHONPATH
A directory to add to the Python path, e.g.
"/home/djangoprojects/myproject".
--traceback Print traceback on exception
--noinput Tells Django to NOT prompt the user for input of any
kind.
--failfast Tells Django to stop running the test suite after
first failed test.
--testrunner=TESTRUNNER
Tells Django to use specified test runner class
instead of the one specified by the TEST_RUNNER
setting.
--liveserver=LIVESERVER
Overrides the default address where the live server
(used with LiveServerTestCase) is expected to run
from. The default value is localhost:8081.
-t TOP_LEVEL, --top-level-directory=TOP_LEVEL
Top level of project for unittest discovery.
-p PATTERN, --pattern=PATTERN
The test matching pattern. Defaults to test*.py.
--version show program version number and exit
-h, --help show this help message and exit
Ответы
Ответ 1
Django не запускает тесты в отдельном процессе; связанный ответ, утверждая, что он делает это просто неправильно. (Ближайшим является тег LiveServerTestCase
для тестов Selenium, который запускает отдельный поток для запуска сервера разработки, но это все еще не отдельный процесс, и это не мешает использованию pdb). Вы должны иметь возможность вставлять import pdb; pdb.set_trace()
в любом месте теста (или в тестируемый код) и получать полезную подсказку pdb. У меня никогда не было проблем с этим, и я просто проверил его снова в новом проекте с Django 1.5.1 и django-Discover-runner 1.0. Если это не работает для вас, это связано с чем-то еще в вашем проекте, а не из-за Django или django-Discover-runner.
Нос фиксирует все выходные данные по умолчанию, что прерывает import pdb; pdb.set_trace()
. Опция -s
отключает захват вывода. Это не обязательно для тестового бегуна Django или django-Discover-runner, так как ни один из них не выполняет вывод-захват для начала.
Я не знаю никакого эквивалента носу --pdb
, если вы используете django-discover-runner. Существует django-pdb проект, который обеспечивает это, но быстрое прочтение его кода подсказывает мне, что он не будет хорошо играть с django -Откройте-бегун; его код может дать вам некоторые подсказки для реализации этого сами. Тем не менее.
FWIW, лично я использую py.test с pytest-django, а не django-Discover-runner или django-nose. И хотя py.test предоставляет параметр --pdb
, такой как нос, я его не использую; Я часто хочу сломать раньше фактической точки ошибки, чтобы выполнить выполнение до ошибки, поэтому я обычно просто вставляю import pytest; pytest.set_trace()
(импортирование set_trace
из pytest
делает эквивалент носа -s
; он отключает захват вывода py.test перед запуском pdb), где я хочу его в коде, а затем удалять его, когда я закончил. Я не считаю это обременительным; YMMV.
Ответ 2
Попробуйте использовать ipdb вместо pdb -
import ipdb;ipdb.set_trace()
или (работает в случае бегуна для тестирования носа)
from nose.tools import set_trace;set_trace()