【问题标题】:Testing Django querysets: self.assertListEqual vs self.assertQuerysetEqual测试 Django 查询集:self.assertListEqual vs self.assertQuerysetEqual
【发布时间】:2017-05-05 04:17:08
【问题描述】:

在 Django 中测试我发现了两种不同的方法来测试涉及查询集的函数。第一个是:

test_instance = FooFactory()
self.assertListEqual(list(Foo.objects.all()), [test_instance])

第二个是:

test_instance = FooFactory()
self.assertQuerysetEqual(Foo.objects.all(), map(repr, [test_instance]))

这两个哪个更好?我从Django docs 读到这是assertQuerysetEqual 所做的:

断言一个查询集 qs 返回一个特定的值列表。

qs和values的内容的比较是使用函数transform进行的;默认情况下,这意味着比较每个值的 repr()。如果 repr() 没有提供独特或有用的比较,则可以使用任何其他可调用对象。

默认情况下,比较也取决于顺序。如果 qs 不提供隐式排序,您可以将 ordered 参数设置为 False,这会将比较转换为 collections.Counter 比较。如果顺序未定义(如果给定的 qs 未排序并且比较针对多个有序值),则会引发 ValueError。

我在这里看到两件重要的事情:一是比较每个值的 repr(),二是 assertQuerysetEqual 允许您将排序设为可选。

对于第一点,我认为最好比较模型本身而不是它们的 repr 值,因为那时您知道它们完全相同(尽管也可以提出 repr 值应该不同的论点)。

第二个,我可以看到无序比较是如何有用的。再说一次,如果你专门测试排序不重要/很容易模拟的东西,我看不到那里的优势。

对于assertQuerysetEqual(基于上述假设),我能想到的唯一论点是它的目的更易读/更直接。

self.assertListEqual(list(<queryset>), [<expected_models_in_correct_order>])self.assertQuerysetEqual(<queryset>, map(repr, [<expected_models_in_correct_order>]) 之间是否存在我未能解释的实际差异?

【问题讨论】:

    标签: python django python-unittest django-testing


    【解决方案1】:

    唯一实际的区别在于 python 如何进行对象和字符串比较。

    self.assertListEqual:比较委托给__eq__ 方法的模型实例列表,该方法提供了如何进行比较的规则。 See how Django does comparison for model instances.

    self.assertQuerysetEqual:使用每个字符串中每个字符的ord 值比较字符串列表。

    根据为对象实现__eq____repr__ 的方式,其中一个可能会比另一个提供轻微的性能提升。

    【讨论】:

      猜你喜欢
      • 2013-11-26
      • 2020-06-05
      • 1970-01-01
      • 2011-11-13
      • 2012-03-29
      • 2015-12-30
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      相关资源
      最近更新 更多