【问题标题】:Django : fixtures object not retrievableDjango:固定装置对象不可检索
【发布时间】:2018-05-30 16:07:08
【问题描述】:

我没有看到 LiveServerTestCase 没有加载固定装置的任何地方,但是当我执行以下操作时:

class FrontTest(LiveServerTestCase):

    fixtures = ['event.json']


    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        print(Event.objects.all())

输出是:

Using existing test database for alias 'default'...
[]

当我使用TestCase

class FrontTest(TestCase):

    fixtures = ['event.json']


    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        print(Event.objects.all())

输出是:

[<Event: event search>]

你知道为什么我的夹具只在 TestCase 中加载吗?我真的很想让它使用 Selenium。谢谢!

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,
       }
    }, 

【问题讨论】:

  • 你的目录结构是什么?
  • 您是否收到任何其他消息(例如抱怨找不到夹具的测试用例)?
  • 不,我的夹具已加载,因为如果我更改“标题”字段并加载我的测试,会有以下输出:Event has no field named 'titles'
  • 会不会是因为LiveServerTestCase
  • 我不认为您使用 SQLite 作为测试数据库是吗?

标签: python django testing fixtures


【解决方案1】:

这是因为TransactionTestCase 在实例的setUp 方法中加载了fixtures,所以它的子类包括LiveServerTestCase 执行相同的操作——除了TestCase,它使用每个类的单个原子事务并在@987654326 中加载fixtures @ 加快测试执行速度。此行为是在#20392 中添加的。

这对您来说意味着您应该将所有与数据库相关的代码从setupClass 移动到LiveServerTestCase 子类中的setUp

class FrontendLiveTest(LiveServerTestCase):

    def setUp(self):
        # the transaction is opened, fixtures are loaded
        assert Event.objects.exists()

注意

如果您尝试将TestCases 原子事务与LiveServerTestCases 后台线程混合:如LiveServerTestCase 文档中所述,

它继承自 TransactionTestCase 而不是 TestCase,因为线程不共享相同的事务(除非使用内存中的 sqlite)并且每个线程都需要提交所有事务,以便其他线程可以查看更改。

【讨论】:

  • 非常感谢!什么都试过了!也谢谢你教我exists 方法!
  • 很好,很高兴我能帮上忙!
【解决方案2】:

首先,遗憾的是,Django 会忽略它找不到的固定装置。您看到的错误意味着 Django 无法找到夹具文件并失败并显示警告:https://code.djangoproject.com/ticket/18990

以下是 Django 查找固定装置的方式:
  • 使用夹具文件的绝对路径,这不是一个好主意,因为夹具可能作为代码的一部分放置 -> 这将覆盖第二种技术
  • 它在settings.FIXTURE_DIRS下定义的所有目录下查找
  • 它会在所有 应用程序目录 下查找一个按惯例称为 fixtures 的文件夹。

基于此,查看你的文件所在的位置,就可以解决这个问题

这是fixture_dirs 的 Django 代码:

@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

【讨论】:

  • 找到我的夹具是因为当我更改字段时,我在测试时有一个Problem installing fixture
猜你喜欢
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 2011-04-29
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多