Ответ 1
Я использую обходные переменные среды в моем проекте (работает только в unix-подобных оболочках)
berry$ myvar=myval ./manage.py test
в вашем модуле прочитайте это значение, используя
os.environ.get('myvar')
Можно ли передать аргументы командной строки сценарию Django manage.py
, в частности, для модульных тестов? т.е. если я что-то вроде
manage.py test myapp -a do_this
Могу ли я получить значение do_this
в функции setUp
модульного теста?
PS @Martin попросил обоснование использования аргументов командной строки в тестах:
Некоторые обширные тесты занимают много времени и не нужно запускать перед каждой фиксацией. Я хочу сделать их необязательными.
Иногда отладочные сообщения, напечатанные в моих тестовых случаях, должны быть необязательными
Иногда я просто хочу, чтобы тесты сошли с ума и попробовали намного больше перестановок данных.
Все вышеперечисленное было бы весьма удобно с параметрами командной строки. Время от времени тестирование может быть намного более обширным или подробным, иначе оно будет быстрым.
Я использую обходные переменные среды в моем проекте (работает только в unix-подобных оболочках)
berry$ myvar=myval ./manage.py test
в вашем модуле прочитайте это значение, используя
os.environ.get('myvar')
Я просто столкнулся с этой проблемой сам, и я хотел избежать установки переменных окружения в командной строке. Экологические переменные, безусловно, работают, но трудно отслеживать, какие переменные имеют эффект, и нет сообщения об ошибке, чтобы сообщить вам, если вы ошиблись в одном из них.
Чтобы обойти это, я использовал argparse
для извлечения дополнительных параметров в аргумент командной строки. Например, мой файл manage.py
теперь выглядит примерно так:
#!/usr/bin/env python
import os
import sys
import argparse
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
argv = sys.argv
cmd = argv[1] if len(argv) > 1 else None
if cmd in ['test']: # limit the extra arguments to certain commands
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--foo', default='bar')
args, argv = parser.parse_known_args(argv)
# We can save the argument as an environmental variable, in
# which case it to retrieve from within 'project.settings',
os.environ['FOO'] = args.foo
# or we can save the variable to settings directly if it
# won't otherwise be overridden.
from django.conf import settings
settings.foo = args.foo
from django.core.management import execute_from_command_line
# parse_known_args strips the extra arguments from argv,
# so we can safely pass it to Django.
execute_from_command_line(argv)
argparse
- действительно хорошая библиотека с множеством функций. Там хороший учебник по нему в документах Python.
В качестве альтернативного manage.py test -a do_this
для управления.py manage.py test -a do_this
вы можете использовать определенный файл настроек
manage.py --settings=project.test_settings test
и определите в этом файле все, что захотите.
# test_setting.py
SPECIFIC_OPTION = "test"
# tests.py
from django.conf import settings
...
def setUp(self):
if settings.SPECIFIC_OPTION:
....
Если вам нужны действительно динамические параметры, возможно, вы можете использовать sys.argv
в test_settings.py
, но это действительно грязный хак.
Django позволяет добавлять пользовательские параметры командной строки из класса testrunner. Вы можете создать подкласс класса testrunner по умолчанию и добавить свои собственные параметры, а затем позволить django использовать ваш собственный testrunner следующим образом.
Например, создайте testrunner.py в каталоге проекта Django, содержащем:
from django.test.runner import DiscoverRunner
class TestRunner(DiscoverRunner):
def __init__(self, option=None, **kwargs):
super().__init__(**kwargs)
print("Passed option: {}".format(option))
@classmethod
def add_arguments(cls, parser):
DiscoverRunner.add_arguments(parser)
parser.add_argument('-o', '--option', help='Example option')
Это testrunner, который происходит от лидера по умолчанию (поэтому он работает так же, как и по умолчанию), за исключением того, что он сообщает django добавить дополнительный параметр командной строки (в add_arguments()
класса add_arguments()
) и обрабатывает значение этой дополнительной опции в конструктор. Чтобы запустить этот новый бегун, пропустите его имя следующим образом:
./manage.py test --testrunner=testrunner.TestRunner -o foo
Конечно, вы можете поместить этот класс в другое место, если вы передадите ему полное имя импорта в командной строке.
Обратите внимание, что вы должны использовать --testrunner=foo
, вы не можете использовать два отдельных аргумента (--testrunner foo
), так как дополнительные аргументы не работают. Исправлено исправление: https://github.com/django/django/pull/10307
Этот пример просто печатает значение параметра, но вы хотите каким-то образом передать его в свой тестовый файл. Я не мог найти никакой быстрой информации о том, как передавать параметры для unittest testcases, но вы могли бы просто использовать глобальную (модульный уровень) переменную или переменную класса для этого (что не так привлекательно и элегантно, но легко и просто работает).