Джанго: объект приспособления не восстановимы
Я нигде не видел, чтобы LiveServerTestCase не загружал светильники, но когда я выполняю следующее:
class FrontTest(LiveServerTestCase):
fixtures = ['event.json']
@classmethod
def setUpClass(cls):
super().setUpClass()
print(Event.objects.all())
Вывод:
Using existing test database for alias 'default'...
[]
While when I use TestCase
class FrontTest(TestCase):
fixtures = ['event.json']
@classmethod
def setUpClass(cls):
super().setUpClass()
print(Event.objects.all())
Результат таков:
[<Event: event search>]
Знаете ли вы, почему мое приспособление загружается только в TestCase ? Я бы очень хотел, чтобы это сработало, чтобы использовать селен. Спасибо!
PS: event.json :
{
"model": "mezzanine_agenda.event",
"pk": 1,
"fields": {
"comments_count": 0,
"keywords_string": "",
"rating_count": 0,
"rating_sum": 0,
"rating_average": 0.0,
"site": 1,
"title": "event search",
"slug": "event-search",
"_meta_title": "",
"description": "event search",
"gen_description": true,
"created": "2018-05-25T15:49:55.223Z",
"updated": "2018-05-25T15:49:55.257Z",
"status": 2,
"publish_date": "2018-05-25T15:49:32Z",
"expiry_date": null,
}
},
2 ответа:
Это потому, что
TransactionTestCase
загружает фикстуры в метод instance'setUp
, поэтому его дочерние классы, включаяLiveServerTestCase
, делают то же самое - за исключениемTestCase
, который использует одну атомарную транзакцию на класс и загружает фикстуры вsetUpClass
, чтобы ускорить выполнение теста. Это поведение было добавлено в #20392.Это означает, что вы должны переместить весь код, связанный с базой данных, из
setupClass
вsetUp
в дочерние классыLiveServerTestCase
:class FrontendLiveTest(LiveServerTestCase): def setUp(self): # the transaction is opened, fixtures are loaded assert Event.objects.exists()
Примечание
На случай, если вы попытаетесь перепутать атомарные транзакции
TestCase
s с фоновыми потокамиLiveServerTestCase
s: как указано вLiveServerTestCase
docs,Он наследуется от
TransactionTestCase
вместоTestCase
, потому что потоки не используют одни и те же транзакции (если только они не используют in-memorysqlite
), и каждый поток должен зафиксировать все свои транзакции, чтобы другой поток мог видеть изменения.
Во-первых, и, к сожалению, Django игнорирует приспособления, которые он не находит. Ошибка, которую вы видите, означает, что Django не смог найти файл fixture и выдает предупреждение: https://code.djangoproject.com/ticket/18990
Вот как Джанго находит светильники:
- Использование абсолютных путей к файлам fixture, не очень хорошая идея, так как fixture, вероятно, помещается как часть кода - > это переопределит второй метод
- он смотрит под всеми каталогами, определенными под
settings.FIXTURE_DIRS
- Он смотрит под всеми каталогами приложений внутри папки, называемой
fixtures
по соглашению.Основываясь на этом, посмотрите, где находится ваш файл, и вы можете исправить эту проблему
Вот код Django для
fixture_dirs
:@cached_property def fixture_dirs(self): """ Return a list of fixture directories. The list contains the 'fixtures' subdirectory of each installed application, if it exists, the directories in FIXTURE_DIRS, and the current directory. """ dirs = [] fixture_dirs = settings.FIXTURE_DIRS if len(fixture_dirs) != len(set(fixture_dirs)): raise ImproperlyConfigured("settings.FIXTURE_DIRS contains duplicates.") for app_config in apps.get_app_configs(): app_label = app_config.label app_dir = os.path.join(app_config.path, 'fixtures') if app_dir in fixture_dirs: raise ImproperlyConfigured( "'%s' is a default fixture directory for the '%s' app " "and cannot be listed in settings.FIXTURE_DIRS." % (app_dir, app_label) ) if self.app_label and app_label != self.app_label: continue if os.path.isdir(app_dir): dirs.append(app_dir) dirs.extend(list(fixture_dirs)) dirs.append('') dirs = [upath(os.path.abspath(os.path.realpath(d))) for d in dirs] return dirs