Как использовать 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()