Как использовать «обнаружить» для запуска тестов в моем каталоге «тесты»? - PullRequest
1 голос
/ 10 апреля 2019

Использование DJango / Python 3.7.Я прочитал здесь - Как мне запустить все модульные тесты Python в каталоге? , чтобы я мог использовать команду "обнаружить", чтобы найти тесты в указанном каталоге.Я хочу иметь папку "tests", поэтому я создал ее и затем запустил

(venv) localhost:myproject davea$ python -m unittest discover tests
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/__main__.py", line 18, in <module>
    main(module=None)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 100, in __init__
    self.parseArgs(argv)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 124, in parseArgs
    self._do_discovery(argv[2:])
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 244, in _do_discovery
    self.createTests(from_discovery=True, Loader=Loader)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 154, in createTests
    self.test = loader.discover(self.start, self.pattern, self.top)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/loader.py", line 344, in discover
    raise ImportError('Start directory is not importable: %r' % start_dir)
ImportError: Start directory is not importable: 'tests'

Это странно для меня, потому что у меня есть (пустой) файл инициализации ...

(venv) localhost:myproject davea$ ls web/tests/
__init__.py  model_tests.py

Что еще мне нужно сделать, чтобы распознать мой тестовый каталог?

Редактировать: Ниже приведено содержимое model_tests.py ...

from django.conf import settings
from django.test import TestCase
from django.core import management


def setup():
    print("setup")
    management.call_command('loaddata', 'test_data.yaml', verbosity=0)


def teardown():
    management.call_command('flush', verbosity=0, interactive=False)


class ModelTest(TestCase):

    # Verify we can correctly calculate the amount of taxes when we are working
    # with a state whose tax rates are defined in our test data
    def test_calculate_tax_rate_for_defined_state(self):
        state = "MN"
        income = 30000
        taxes = IndividualTaxBracket.objects.get_taxes_owed(state, income)
        print(taxes)
        self.assertTrue(taxes > 0, "Failed to calucate taxes owed properly.")

Ответы [ 4 ]

0 голосов
/ 16 апреля 2019

Для завершения ...

Вы уже знаете эту форму здесь :

Имена ваших тестов и файлов должны соответствовать определенному шаблону, чтобы их можно было обнаружить по discover().

Но тогда вы получили эту ошибку:

"django.core.exceptions.ImproperlyConfigured: запрошенные параметры, но параметры не настроены"

Это означает, что Django не смог найти свои настройки во время выполнения ваших тестов. Вы можете указать, где искать настройки, используя переменную окружения:

DJANGO_SETTINGS_MODULE='myproyect.settings' python3 -m unittest discover

Ссылка: https://docs.djangoproject.com/en/2.2/topics/settings/#designating-the-settings

С другой стороны ...

Вы должны запустить свои тесты Django с

./manage.py tests

это автоматически выполнит поиск тестов с использованием того же механизма, что и discover(), и, поскольку вы будете запускать команду Django, у вас будут некоторые преимущества от непосредственного запуска тестов Django.


@ Nafees Anwar спросил: Как настройка переменной среды изменяет настройки?

В самом начале файла model_tests.py есть строка from django.conf import settings, при создании экземпляра настроек LazyObject Django будет искать эту переменную среды. Прочитайте код для более подробной информации.

Я выложу здесь фрагмент кода для иллюстрации.

# django.conf module.
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"


class LazySettings(LazyObject):
    """
    A lazy proxy for either global Django settings or a custom settings object.
    The user can manually configure settings prior to using them. Otherwise,
    Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
    """
    def _setup(self, name=None):
        """
        Load the settings module pointed to by the environment variable. This
        is used the first time we need any settings at all, if the user has not
        previously configured the settings manually.
        """
        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        if not settings_module:
            desc = ("setting %s" % name) if name else "settings"
            raise ImproperlyConfigured(
                "Requested %s, but settings are not configured. "
                "You must either define the environment variable %s "
                "or call settings.configure() before accessing settings."
                % (desc, ENVIRONMENT_VARIABLE))

        self._wrapped = Settings(settings_module)

Итак, если вы сделаете:

from django.conf import settings

установив эту переменную окружения, оператор

settings.configure()

потерпит неудачу с RuntimeError('Settings already configured.')

0 голосов
/ 12 апреля 2019

Я думаю, у вас возникли некоторые сомнения по поводу команды discover.Согласно документам.

Unittest поддерживает простое обнаружение тестов.Чтобы быть совместимым с обнаружением тестов, все тестовые файлы должны быть модулями или пакетами (включая пакеты пространства имен), импортируемыми из каталога верхнего уровня проекта (это означает, что их имена файлов должны быть действительными идентификаторами).

Это означает, что все тестовые файлы должны быть импортируемыми из каталога, из которого вы запускаете команду (каталог, в котором находится каталог web).Это гарантирует, что все тестовые файлы должны быть в допустимых пакетах Python (каталоги, содержащие __init__.py).

Во-вторых, вы запускаете команду python -m unittest discover tests, что неверно.Вам не нужно добавлять tests в конце.Юнит-тесты с поддержкой команды Discover 4 опции.Вы можете прочитать больше об этом здесь .

У меня следующая структура каталогов.

 web
    ├── __init__.py
    └── tests
        ├── __init__.py
        └── test_models.py

И я выполняю следующую команду.

python3 -m unittest discover

со следующими результатами.

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK
0 голосов
/ 15 апреля 2019

Если файл с именем tests.py существует как одноуровневый модуль tests, это, вероятно, вызовет упомянутый ImportError, и удаление test.py должно исправить его.

Если все еще не обнаружены модульные тестыпара вопросов в следующем порядке:

1) содержит ли тестовый модуль хотя бы класс, производный от django.test.TestCase?

2) и в этом случае этот класссодержать хотя бы один метод, имя которого начинается с «test _»

Обратите внимание, что имя любого файла, содержащего модульный тест, должно начинаться с «test».

Итакmodel_test.py не будет работать;Обычно он используется для настройки некоторых поддельных моделей, но модульные тесты должны находиться в другом месте.

Вы можете обнаружить и запустить тесты с помощью этой команды управления:

python manage.py test

или

python manage.py test appname

Есть ли какая-либо конкретная причина для использования python -m unittest discover вместо этого?Я думаю, это тоже может сработать, но тогда вам придется вручную загрузить среду django

0 голосов
/ 12 апреля 2019

Перво-наперво: наличие __init__.py не является чем-то необычным, потому что __init__.py сообщает python, что каталог является модулем; Обычно это пустой файл __init__.py. У меня была та же ошибка, и я исправил ее, переименовав каталог ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...