【问题标题】:Django manage.py test cannot load fixture properlyDjango manage.py 测试无法正确加载夹具
【发布时间】:2013-08-24 21:03:54
【问题描述】:

我已经使用 django.test.TestCase 编写了 Django 测试,并且我想使用带有我当前所有数据库数据的夹具来运行测试。但是,如果我按如下方式创建夹具:

python manage.py dumpdata --indent=3 > myapp/fixtures/test_data.json

当我使用 python manage.py test myapp 运行测试时,我收到以下错误:

Problem installing fixture...(traceback)
IntegrityError: Could not load auth.Permission(pk=42): duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key"
DETAIL:  Key (content_type_id, codename)=(14, add_record) already exists.

我在某处读到这可能是由 pk 冲突引起的,所以我尝试使用以下方法重新创建夹具:

python manage.py dumpdata --natural --indent=3 > myapp/fixtures/test_data.json

但是现在运行测试给了我:

Problem installing fixture...(traceback)
DeserializationError: 'NoneType' object has no attribute '_meta'

我也尝试过各种排除(使用 --exclude 选项)auth.permissioncontenttypes(或同时排除),但后来我收到有关缺少权限 (Key (permission_id)=(44) is not present in table "auth_permission".) 或缺少内容类型 (@ 987654331@)

问题是,无论如何我都需要权限,因为我的测试部分是为了验证只有具有特定权限的用户才能访问某些视图。

老实说,我不明白为什么会发生这种情况——我的印象是测试运行程序从一个完全干净的数据库开始并从我的夹具中加载所有内容,但是阅读这样的帖子:Django unit-testing with loading fixtures for several dependent applications problems 成功了好像不是这样的。

我该如何解决这个问题?我宁愿不必写类似的东西 在我的测试中,User.objects.create_user(..def setUp(self): 下的无数次只是为了有足够的对象让它们正常运行......

【问题讨论】:

    标签: django unit-testing django-testing django-fixtures


    【解决方案1】:

    即使使用 --natural,问题似乎仍然存在。 但是,它似乎在 django1.9 中用新标志解决了: dumpdata --natural-foreign --natural-primary

    https://code.djangoproject.com/ticket/21278#comment:5

    【讨论】:

    • 对于遇到类似问题的任何人,这里有一个关键见解:如果您的模型包含 M2M 关系,请不要将 M2M 表转储到您的测试夹具中!否则,M2M 将在创建相关对象时首先填充,然后在从夹具加载 M2M 数据时再次填充,从而导致完整性错误。
    【解决方案2】:

    当您运行测试时,initial_data fixtures will be loaded (by syncdb)

    对我来说,dumpdata--natural 参数一起使用,不包括 contenttypes,然后手动删除一些 auth.permission 条目,只剩下这些:

    {
        "pk": 1, 
        "model": "auth.permission", 
        "fields": {
            "codename": "add_permission", 
            "name": "Can add permission", 
            "content_type": [
                "auth", 
                "permission"
            ]
        }
    },
    {
        "pk": 2, 
        "model": "auth.permission", 
        "fields": {
            "codename": "change_permission", 
            "name": "Can change permission", 
            "content_type": [
                "auth", 
                "permission"
            ]
        }
    },
    {
        "pk": 3, 
        "model": "auth.permission", 
        "fields": {
            "codename": "delete_permission", 
            "name": "Can delete permission", 
            "content_type": [
                "auth", 
                "permission"
            ]
        }
    },
    {
        "pk": 4, 
        "model": "auth.permission", 
        "fields": {
            "codename": "add_group", 
            "name": "Can add group", 
            "content_type": [
                "auth", 
                "group"
            ]
        }
    },
    {
        "pk": 5, 
        "model": "auth.permission", 
        "fields": {
            "codename": "change_group", 
            "name": "Can change group", 
            "content_type": [
                "auth", 
                "group"
            ]
        }
    },
    {
        "pk": 6, 
        "model": "auth.permission", 
        "fields": {
            "codename": "delete_group", 
            "name": "Can delete group", 
            "content_type": [
                "auth", 
                "group"
            ]
        }
    },
    {
        "pk": 7, 
        "model": "auth.permission", 
        "fields": {
            "codename": "add_user", 
            "name": "Can add user", 
            "content_type": [
                "auth", 
                "user"
            ]
        }
    },
    {
        "pk": 8, 
        "model": "auth.permission", 
        "fields": {
            "codename": "change_user", 
            "name": "Can change user", 
            "content_type": [
                "auth", 
                "user"
            ]
        }
    },
    {
        "pk": 9, 
        "model": "auth.permission", 
        "fields": {
            "codename": "delete_user", 
            "name": "Can delete user", 
            "content_type": [
                "auth", 
                "user"
            ]
        }
    },
    {
        "pk": 10, 
        "model": "auth.permission", 
        "fields": {
            "codename": "add_contenttype", 
            "name": "Can add content type", 
            "content_type": [
                "contenttypes", 
                "contenttype"
            ]
        }
    },
    {
        "pk": 11, 
        "model": "auth.permission", 
        "fields": {
            "codename": "change_contenttype", 
            "name": "Can change content type", 
            "content_type": [
                "contenttypes", 
                "contenttype"
            ]
        }
    },
    {
        "pk": 12, 
        "model": "auth.permission", 
        "fields": {
            "codename": "delete_contenttype", 
            "name": "Can delete content type", 
            "content_type": [
                "contenttypes", 
                "contenttype"
            ]
        }
    },
    {
        "pk": 13, 
        "model": "auth.permission", 
        "fields": {
            "codename": "add_session", 
            "name": "Can add session", 
            "content_type": [
                "sessions", 
                "session"
            ]
        }
    },
    {
        "pk": 14, 
        "model": "auth.permission", 
        "fields": {
            "codename": "change_session", 
            "name": "Can change session", 
            "content_type": [
                "sessions", 
                "session"
            ]
        }
    },
    {
        "pk": 15, 
        "model": "auth.permission", 
        "fields": {
            "codename": "delete_session", 
            "name": "Can delete session", 
            "content_type": [
                "sessions", 
                "session"
            ]
        }
    },
    {
        "pk": 16, 
        "model": "auth.permission", 
        "fields": {
            "codename": "add_site", 
            "name": "Can add site", 
            "content_type": [
                "sites", 
                "site"
            ]
        }
    },
    {
        "pk": 17, 
        "model": "auth.permission", 
        "fields": {
            "codename": "change_site", 
            "name": "Can change site", 
            "content_type": [
                "sites", 
                "site"
            ]
        }
    },
    {
        "pk": 18, 
        "model": "auth.permission", 
        "fields": {
            "codename": "delete_site", 
            "name": "Can delete site", 
            "content_type": [
                "sites", 
                "site"
            ]
        }
    },
    

    我不明白为什么,但它确实有效。我会尝试在syncdb 之后直接将我的夹具与新数据库的转储进行比较,然后决定在我的夹具中删除或编辑什么。希望这对您的情况有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-10-24
      • 2011-03-10
      • 2018-02-07
      • 2011-01-12
      • 2014-12-20
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多