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


165

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

$ ./manage.py test animals.AnimalTestCase

Це передбачає, що ви маєте свої тести у файлі testing.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Файл має функцію ванній ():

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

Як вказати окремий тестовий випадок, коли мої тести містяться у кількох файлах?

Відповіді:


156

Замовлення Джанго-ніс . Це дозволяє вказати тести для запуску на зразок:

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

або як зазначено в коментарях, використовуйте синтаксис:

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

Дякую @sdolan. Зустрічався з тією ж проблемою, що і гекевінтран. Переключений на джанго-нос, і це виправлено, також працює набагато краще, ніж тест-бігун Django за замовчуванням.
LeeMobile

Це запускає тест, але як запустити цілий TestCase?
jMyles

5
@jMyles:another.test:TestCase
Сем Долан

4
До уваги такі люди, як я, які сліпо вставляють з Stackoverflow: це помилка без згаданого плагіна, використовуйте синтаксис, описаний в іншій відповіді (. Замість :), який працює в Django 1.6+.
Енді Сміт

1
Я відповів на цю відповідь, оскільки він насправді не відповідає на питання ОП, що було робити в Джанго. Швидше, це просто пропонує перейти на Nosetest
Джош Браун

175

Оскільки Django 1.6, ви можете запустити повний тестовий випадок або один тест, використовуючи повне позначення крапок для елемента, який потрібно запустити.

Автоматичне виявлення тестів тепер знайде тести у будь-якому файлі, який починається з тестування в робочому каталозі, тому вирішуючи питання, вам доведеться перейменувати свої файли, але тепер ви можете зберігати їх у потрібному каталозі. Якщо ви хочете використовувати власні імена файлів, ви можете вказати шаблон (тестовий бігун Django за замовчуванням) з позначкою параметра --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


Приємно бачити цю функцію, вбудовану в Django зараз.
hekevintran

Я взагалі не можу змусити це працювати: error: option --pattern not recognizedіinvalid command name
геодезичний

Це чудово працює у Django v3!
Кірк

11

Я мав цю проблему сам і знайшов це питання, якщо хтось інший прийде, ось що я викопав. DjangoTestSuiteRuner використовує метод під назвою build_test (label), який визначає, які тестові випадки запускати на основі мітки. Якщо вивчити цей метод, виявляється, що вони роблять getattr () або на "моделях", або на "тестовому" модулі. Це означає, що якщо ви повернете набір, тест-бігун не шукає ваші тестові випадки в цьому наборі, він виглядає лише в одному з цих модулів.

Швидке обіймати - це використовувати __init__.py для імпорту ваших тестів безпосередньо замість визначення набору. Робить їх частиною "тестового" модуля, і тому build_test (мітка) може їх знайти.

Для вашого прикладу вище, він tests/__init__.pyповинен просто містити:

from field_tests import *
from storage_tests import *

Це не дуже елегантно, і, звичайно, якщо ви намагаєтеся зробити щось складніше зі своїм набором, то це не вийде, але це було б у цьому випадку.




3

Помістіть цей код у свій __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")

Тепер все, що вам потрібно зробити для нових тестів, це написати їх і переконатися, що вони знаходяться в папці тестів. Немає більше нудного забезпечення імпорту!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.