Я поместил некоторые модульные тесты в mysite/vncbrowser/tests.py
, и я могу запустить их с:
cd mysite
python manage.py test vncbrowser
В tests.py
, я импортирую классы моделей с помощью:
from vncbrowser.models import Project, Stack, Integer3D, Double3D
... и проверить вставку Integer3D
в пользовательский тип поля с помощью теста вроде:
class InsertionTest(TestCase):
def test_stack_insertion(self):
s = Stack()
s.title = "Example Stack"
s.image_base = "http://foo/bar/"
s.dimension = Integer3D(x=2048, y=1536, z=460)
s.resolution = Double3D(x=5.0001, y = 5.0002, z=9.0003)
s.save()
self.assertEqual(s.id, 1)
Однако, когда я запускаю тесты с python manage.py test vncbrowser
, я обнаруживаю, что проверкаиз isinstance(value, Integer3D)
в источнике models.py
не удается.Похоже, что в файле models.py
пустая ссылка на Integer3D
(определенная ранее в этом файле) имеет полное имя vncbrowser.models.Integer3D
, в то время как объект, переданный из теста, имеет полное имя mysite.vncbrowser.models.Integer3D
.
Соответствующий код из models.py
с некоторыми операторами отладки:
class Integer3D(object):
[... elided ...]
class Integer3DField(models.Field):
def to_python(self, value):
a = Integer3D()
print >> sys.stderr, "value is %s, of type %s" % (value, type(value))
print >> sys.stderr, "but a new Integer3D instance is", type(a)
if isinstance(value, Integer3D):
print >> sys.stderr, "isinstance check worked"
return value
print >> sys.stderr, "isinstance check failed"
..., который производит этот вывод (с некоторыми символами новой строки и пробелами, добавленными для ясности):
value is <vncbrowser.models.Integer3D object at 0x22bbf90>, of type
<class 'vncbrowser.models.Integer3D'>
but a new Integer3D instance is
<class 'mysite.vncbrowser.models.Integer3D'>
isinstance check failed
Я могу заставить этот тест работать, изменив импорт в tests.py
на:
from mysite.vncbrowser.models import Project, Stack, Integer3D, Double3D
... но я не понимаю, почему квалификация mysite
должна требоваться вtests.py
файл.Кажется, это не требуется где-то еще в моем источнике Django.Я уверен, что упускаю что-то очевидное, но, возможно, кто-то может объяснить?
(Я даже не уверен, почему импорт from mysite....
работает, на самом деле, поскольку, если я печатаю sys.path
из простоперед этим оператором он включает путь /home/mark/foo/mysite/
, но не /home/mark/foo/
.)
Мой текущий рабочий каталог /home/mark/foo/mysite/
, когда я запускаю python manage.py test vncbrowser
.
AsЗапрошенный макет моего проекта выглядит следующим образом:
── mysite
├── custom_postgresql_psycopg2
│ ├── base.py
│ └── __init__.py
├── __init__.py
├── manage.py
├── settings.py
├── urls.py
└── vncbrowser
├── __init__.py
├── models.py
├── tables.sql
├── tests.py
└── views.py
Все перечисленные выше файлы __init__.py
пусты.Я использую Python 2.6.5 и Django 1.3.Я использую Python в virtualenv, и если я печатаю "\n".join(sys.path)
в начале tests.py, я получаю:
/home/mark/foo/mysite
/home/mark/foo/env/lib/python2.6/site-packages/distribute-0.6.10-py2.6.egg
/home/mark/foo/env/lib/python2.6
/home/mark/foo/env/lib/python2.6/plat-linux2
/home/mark/foo/env/lib/python2.6/lib-tk
/home/mark/foo/env/lib/python2.6/lib-old
/home/mark/foo/env/lib/python2.6/lib-dynload
/usr/lib/python2.6
/usr/lib64/python2.6
/usr/lib/python2.6/plat-linux2
/usr/lib/python2.6/lib-tk
/usr/lib64/python2.6/lib-tk
/home/mark/foo/env/lib/python2.6/site-packages
Обновление: , как предложено в lbp's answer , я попытался добавить следующее в верхней части tests.py:
import vncbrowser as vnc_one
import mysite.vncbrowser as vnc_two
print "vnc_one:", vnc_one.__file__
print "vnc_two:", vnc_two.__file__
..., что привело к выводу:
vnc_one: /home/mark/foo/mysite/vncbrowser/__init__.pyc
vnc_two: /home/mark/foo/mysite/../mysite/vncbrowser/__init__.pyc