Запуск определенного тестового примера в Django, когда у вашего приложения есть каталог тестов

#python #django #unit-testing

#python #django #модульное тестирование

Вопрос:

Документация Django (http://docs.djangoproject.com/en/1.3/topics/testing/#running-tests ) говорит, что вы можете запускать отдельные тестовые примеры, указав их:

 $ ./manage.py test animals.AnimalTestCase
  

Это предполагает, что у вас есть тесты в tests.py файл в вашем приложении Django. Если это верно, то эта команда работает так, как ожидалось.

У меня есть мои тесты для приложения Django в каталоге тестов:

 my_project/apps/my_app/
├── __init__.py
├── tests
│   ├── __init__.py
│   ├── field_tests.py
│   ├── storage_tests.py
├── urls.py
├── utils.py
└── views.py
  

tests/__init__.py Файл имеет функцию suite ():

 import unittest

from my_project.apps.my_app.tests import field_tests, storage_tests

def suite():
    tests_loader = unittest.TestLoader().loadTestsFromModule
    test_suites = []
    test_suites.append(tests_loader(field_tests))
    test_suites.append(tests_loader(storage_tests))
    return unittest.TestSuite(test_suites)
  

Для запуска тестов я делаю:

 $ ./manage.py test my_app
  

Попытка указать отдельный тестовый пример вызывает исключение:

 $ ./manage.py test my_app.tests.storage_tests.StorageTestCase
...
ValueError: Test label 'my_app.tests.storage_tests.StorageTestCase' should be of the form app.TestCase or app.TestCase.test_method
  

Я попытался сделать то, что указано в сообщении об исключении:

 $ ./manage.py test my_app.StorageTestCase
...
ValueError: Test label 'my_app.StorageTestCase' does not refer to a test
  

Как мне указать отдельный тестовый пример, когда мои тесты находятся в нескольких файлах?

Ответ №1:

Начиная с Django 1.6, вы можете запускать полный тестовый пример или отдельный тест, используя полную точечную нотацию для элемента, который вы хотите запустить.

Автоматическое обнаружение тестов теперь найдет тесты в любом файле, который начинается с test в рабочем каталоге, поэтому для решения вопроса вам придется переименовать свои файлы, но теперь вы можете сохранить их в нужном каталоге. Если вы хотите использовать пользовательские имена файлов, вы можете указать шаблон (по умолчанию Django test runner) с флагом option --pattern="my_pattern_*.py" .

Итак, если вы находитесь в своем manage.py каталоге и хотите запустить тест test_a внутри TestCase подкласса A внутри файла tests.py в приложении / модуле example , вы бы сделали:

 python manage.py test example.tests.A.test_a
  

Если вы не хотите включать зависимость и находитесь в Django 1.6 или более поздней версии, вот как вы это делаете.

Смотрите документацию Django для получения дополнительной информации

Комментарии:

1. Я вообще не могу заставить это работать: error: option --pattern not recognized и invalid command name

Ответ №2:

Ознакомьтесь с django-nose. Это позволяет вам указать тесты для запуска следующим образом:

 python manage.py test another.test:TestCase.test_method
  

или, как указано в комментариях, используйте синтаксис:

 python manage.py test another.test.TestCase.test_method
  

Комментарии:

1. Спасибо @sdolan. Столкнулся с той же проблемой, что и hekevintran. Переключился на django-nose, и это устранило эту проблему, также работает намного лучше, чем тестовый запуск Django по умолчанию.

2. Это запускает тест, но как запустить весь тестовый пример?

3. @jMyles: another.test:TestCase

4. Внимание, такие люди, как я, которые слепо вставляют из Stackoverflow: Это приведет к ошибке без упомянутого плагина, используйте синтаксис, описанный в другом ответе (. вместо :), который работает в Django 1.6 .

5. я отклонил этот ответ, потому что он фактически не отвечает на вопрос OP, который заключался в том, как это сделать в Django. Скорее, это просто предлагает переключиться на Nosetest

Ответ №3:

Это должно сработать-

 python manage.py test my_app.tests.storage_tests
  

Ответ №4:

У меня самого была эта проблема, и я нашел этот вопрос, на случай, если кто-нибудь еще придет, вот что я откопал. DjangoTestSuiteRuner использует метод под названием build_test(label), который определяет, какие тестовые примеры запускать на основе метки. Изучая этот метод, оказывается, что они выполняют getattr() либо в модуле «модели», либо в модуле «тест». Это означает, что если вы возвращаете набор, тестировщик не ищет ваши тестовые примеры в этом наборе, он ищет только в одном из этих модулей.

Быстрый обходной путь заключается в использовании __init__.py для импорта ваших тестов напрямую вместо определения набора. Это делает их частью модуля «test», и поэтому build_test (label) может их найти.

Для вашего примера выше tests/__init__.py должно просто содержать:

 from field_tests import *
from storage_tests import *
  

Это не очень элегантно, и, конечно, если вы пытаетесь сделать что-то более сложное со своим пакетом, это не сработает, но в данном случае сработало бы.

Ответ №5:

Используйте -k флаг для запуска определенного теста по имени без указания полного пути:

 ./manage.py test animals.AnimalTestCase -k my_test_name
  

или просто

 ./manage.py test -k my_test_name
  

(Я знаю, что это был не точный вопрос, но эта страница занимает высокое место в поиске Google, когда я пытался разобраться в этом)

Комментарии:

1. работает с ноября 2022

2. Приятно знать, что он все еще работает месяц спустя, лол

Ответ №6:

Поместите этот код в свой __init__.py и он импортирует все тестовые классы в пакете и подпакетах. Это позволит вам запускать определенные тесты без ручного импорта каждого файла.

 import pkgutil
import unittest

for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(module_name).load_module(module_name)
    for name in dir(module):
        obj = getattr(module, name)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            exec ('%s = obj' % obj.__name__)
  

Аналогично, для вашего набора тестов вы можете просто использовать:

 def suite():   
    return unittest.TestLoader().discover("appname.tests", pattern="*.py")
  

Теперь все, что вам нужно сделать для новых тестов, это записать их и убедиться, что они находятся в папке tests. Больше никакого утомительного обслуживания импорта!

Ответ №7:

Я также столкнулся с этой проблемой, и вместо использования django-nose я перешел по этой ссылке здесь:http://www.pioverpi.net/2010/03/10/organizing-django-tests-into-folders /. Вам нужно открыть свой init.py и импортировать ваши тесты.

Например, в init.py: from unique_test_file import *

Комментарии:

1. ваша ссылка не работает, пожалуйста, обновите свой ответ.

Ответ №8:

Если вы хотите запустить класс тестового примера, у которого есть путь <module_name>/tests/test_views.py , вы можете запустить команду python manage.py test <module_name>.tests.test_views.<test_case_name> .