断言django测试中两个对象列表相同

时间:2014-06-02 04:08:31

标签: django django-testing django-tests

有没有办法在django测试中检查两个对象列表是否相等。

我想说我有一些模特:

class Tag(models.Model):
    slug = models.SlugField(max_length=50, unique=True)
    def __unicode__(self):
        return self.slug

我运行这个简单的测试:

def test_equal_list_fail(self):
    tag_list = []
    for tag in ['a', 'b', 'c']:
        tag_list.append(Tag.objects.create(slug=tag))

    tags = Tag.objects.all()

    self.assertEqual(tag_list, tags)

这失败了:

======================================================================
FAIL: test_equal_list_fail (userAccount.tests.ProfileTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "path/to/tests.py", line 155, in test_equal_list_fail
    self.assertEqual(tag_list, tags)
AssertionError: [<Tag: a>, <Tag: b>, <Tag: c>] != [<Tag: a>, <Tag: b>, <Tag: c>]

----------------------------------------------------------------------

这将有效:

def test_equal_list_passes(self):
    tag_list = []
    for tag in ['a', 'b', 'c']:
        tag_list.append(Tag.objects.create(slug=tag))

    tags = Tag.objects.all()

    for tag_set in zip(tags, tag_list):
        self.assertEqual(*tag_set)

然而,这失败了:

def test_equal_list_fail(self):
    tag_list = []
    for tag in ['a', 'b', 'c']:
        tag_list.append(Tag.objects.create(slug=tag))

    tags = Tag.objects.all()

    for tag_set in zip(tags, tag_list):
        print "\n"
        print tag_set[0].slug + "'s pk is %s" % tag_set[0].pk
        print tag_set[1].slug + "'s pk is %s" % tag_set[1].pk
        print "\n"
        self.assertIs(*tag_set)

with:

Creating test database for alias 'default'...
.......

a's pk is 1
a's pk is 1

F.
======================================================================
FAIL: test_equal_list_fail (userAccount.tests.ProfileTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "path/to/tests.py", line 160, in test_equal_list_fail
    self.assertIs(*tag_set)
AssertionError: <Tag: a> is not <Tag: a>

这是预期的行为吗?

修改以回应评论
这种比较有效:

class Obj:
    def __init__(self, x):
        self.x = x

>>> one = Obj(1)
>>> two = Obj(2)
>>> a = [one, two]
>>> b = [one, two]
>>> a == b
True

为什么其他阵列的测试失败?

2 个答案:

答案 0 :(得分:9)

测试两个列表

使用:assertSequenceEqual

因为在这种情况下,tags = Tag.objects.all()会生成django.db.models.query.QuerySettag_list.append(...)会创建一个列表。

不同情况下的其他选择是:

  • assertListEqual(a,b)
  • assertTupleEqual(a,b)
  • assertSetEqual(a,b)
  • assertDictEqual(a,b)

为什么<Tag: a> is not <Tag: a>

标签是相同型号,但它们已被加载到内存中的不同位置

for tag_set in zip(tags, tag_list):
    print "\n"
    print tag_set[0].slug + "'s pk is %s" % tag_set[0].pk + ' id is: ' + id(tag_set[0])
    print tag_set[1].slug + "'s pk is %s" % tag_set[1].pk + ' id is: ' + id(tag_set[1])
    print "\n"
    self.assertIs(*tag_set)

返回

.......

a's pk is 1 id is: 4522000208
a's pk is 1 id is: 4522228112

F.

因此,is将重新审核False

答案 1 :(得分:3)

我认为您要测试的是,如果创建的标签与测试列表中的标签具有相同的标记。

为此,仅将slug作为带有values_list的列表获取,然后比较:

assertEqual(Tag.objects.values_list('slug', flat=True), ['a','b','c'])

我不得不说,这不是一个非常有用的测试,因为你正在检查django orm功能,它已经过很好的测试。

您的测试应检查您自己的应用程序的具体细节。