Как запустить django TestCase вручную/против другой базы данных?
У меня есть некоторые методы, записанные в объект django.test.TestCase
, который я хотел бы запустить из
manage.py shell
в моей реальной базе данных. Но когда я пытаюсь создать экземпляр объекта TestCase для запуска тестового метода, я получаю эту ошибку:
ValueError: no such test method in <class 'track.tests.MentionTests'>: runTest
Есть ли способ создать экземпляр объектов TestCase
? Или есть способ запустить тестовый метод для не-тестовой базы данных?
Ответы
Ответ 1
Вот метод, который я нашел недавно. Я еще не нашел ничего лучшего.
from django.test.utils import setup_test_environment
from unittest import TestResult
from my_app.tests import TheTestWeWantToRun
setup_test_environment()
t = TheTestWeWantToRun('test_function_we_want_to_run')
r = TestResult()
t.run(r)
r.testsRun # prints the number of tests that were run (should be 1)
r.errors + r.failures # prints a list of the errors and failures
В соответствии с документами мы должны называть setup_test_environment()
при проведении вручную тестов. django.test
использует unittest
для тестирования, поэтому мы можем использовать TestResult
от unittest
для получения результатов при запуске теста.
В Django 1.2 DjangoTestRunner
можно использовать для более структурированного тестирования. Я еще не пробовал это.
Ответ 2
Проблема "runTest" обычно возникает, когда люди не замечают того факта, что unittest.TestCase имеет аргумент по умолчанию в своем конструкторе. Посмотрите на lib/python/unittest/case.py
class TestCase:
def __init__(self, methodName='runTest'):
Обратите внимание, что базовый класс "TestCase" не предоставляет стандартную реализацию "def runTest", но он не пытается ее вызвать. То, откуда исходит ошибка. Фактическая путаница исходит из того факта, что использование "unittest.main()" не требует метода runTest, но все равно вызовет все функции "def test *". Это работает... но не из-за поведения по умолчанию TestCase, а из кода проверки с unittest.main - это делает что-то вроде следующего:
class MyTest(unittest.TestCase):
def test_001(self):
print "ok"
if __name__ == "__main__":
suite = unittest.TestSuite()
for method in dir(MyTest):
if method.startswith("test"):
suite.addTest(MyTest(method))
unittest.TextTestRunner().run(suite)
Отвечая на исходный вопрос "У меня есть некоторые методы, написанные в django.test.TestCase": вам нужно добавить каждый метод отдельно в testuite с помощью вашего тестового класса и предоставить имя целевого метода в качестве первого аргумента при создании объекта.
Ответ 3
Из Django docs:
Запуск тестов
Как только вы написали тесты, запустите их используя подкоманду проверки вашего утилита утилиты project.py:
$./manage.py test
По умолчанию это будет проходить каждый тест в каждом приложении INSTALLED_APPS. Если вы только хотите провести тесты для конкретного приложение, добавьте имя приложения в командной строке. Например, если ваш INSTALLED_APPS содержит 'myproject.polls' и 'myproject.animals', вы можете запустить Только тесты myproject.animals с помощью этой команды:
$./manage.py test animals
Обратите внимание, что мы использовали животных, а не myproject.animals. Новое в Django 1.0: Теперь вы можете выбрать, какой тест выполнить.
Вы можете быть более назвав отдельный тестовый пример. Бежать один тестовый пример в приложении (например, AnimalTestCase описанных в "Испытаниях единицы письма", раздел), добавьте название теста case к метке в командной строке:
Тест $./manage.py animals.AnimalTestCase
И он становится еще более зернистым, чем что! Для запуска одного метода тестирования внутри тестового примера добавьте имя метод проверки на метку:
Тест $./manage.py animals.AnimalTestCase.testFluffyAnimals
Последний пример должен быть применим в вашем случае.
Если это то, что вы делаете, вам нужно будет опубликовать более подробное описание кода, используемого в вашем тестовом случае.
Ответ 4
Я столкнулся с этим и разработал следующее решение:
В вашем файле myapp/tests.py задайте такие параметры следующим образом:
# get the straight-up Python unittest without the Django machinery
# NOTE: this is unittest2, a backport of unit testing features from Python 2.7
# (running 2.6 at the time of writing)
from django.utils import unittest
# get the Django wraps
from django.test import TestCase as DjangoTestCase
# [..]
# your normal Django unit tests, inheriting from DjangoTestCase
# [..]
class MyTest( unittest.TestCase ):
def runTest( self ): # NOTE: required name
self.failUnless( True is True )
def runNonDjangoTests():
return MyTest() # or unittest.TestSuite( [ MyTest(), .. ] )
Вы запускаете этот тест с помощью
~$ unit2 myapp.tests.runNonDjangoTests
Для получения дополнительной информации см. http://pypi.python.org/pypi/unittest2
Это также позволяет запускать модульные тесты против основной базы данных со всеми потенциально разрушительными побочными эффектами. Обратите внимание, что unit2 довольно опасен в этом контексте, если вы вызываете
unit2 myapp.tests, он будет запускать все ваши обычные тесты Django, не помещая их в тестовую базу данных.