I faced some strange behavior of the AssertEquals() in a Django unit test (Python 3.4). The following test results in an assertion error like this:

在Django单元测试(Python 3.4)中,我遇到了AssertEquals()的一些奇怪行为。下面的测试会导致这样的断言错误:

line 113, in test_index_view_with_questions_without_choices self.assertEqual(response.context['lastest_question_list'], []) AssertionError: [] != []

第113行,在test_index_view_with_questions_without_choices self.assertEqual(response)中。上下文['lastest_question_list'], []) AssertionError: [] != []

Here's the test itself:

这是测试本身:

def test_index_view_with_questions_without_choices(self):
    '''
    If a question has no choices it should not be
    displayed on the questions index page no matter if it's
    a past or a future question.
    '''
    create_question_with_no_choices(question_text='no choices q1', days=-5)
    create_question_with_no_choices(question_text='no choices q2', days=5)
    response = self.client.get(reverse('polls:index'))
    self.assertContains(response, 'No polls are available.', status_code=200)
    self.assertEqual(response.context['lastest_question_list'], [])

Changing last line like so:

像这样改变最后一行:

self.assertEqual(len(response.context['lastest_question_list']), 0)

makes the test working properly but I can't get the reason it refuses to work with the list itself.

使测试正常工作,但我无法理解它拒绝使用列表本身的原因。

I also have a very similar test in the same app and project and it works just fine:

我在同一个应用程序和项目中也有一个非常相似的测试,它运行得很好:

def test_index_view_with_no_questions(self):
    '''
    If no questions exist, an appropriate message 
    should be displayed.
    '''
    response = self.client.get(reverse('polls:index'))
    self.assertEqual(response.status_code, 200)
    self.assertContains(response, 'No polls are available.')
    self.assertQuerysetEqual(response.context['lastest_question_list'], [])

Here's the view itself to show how the Queryset defined:

下面是显示Queryset是如何定义的视图:

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'lastest_question_list'

    def get_queryset(self):
        '''
        Returns last five published questions
        (not including those set to be published in the future)
        Also excludes the questions with an empty choice_set.
        '''
        qset = Question.objects.annotate(choices_count=Count('choice'))
        qset = qset.filter(choices_count__gte=1, pub_date__lte=timezone.now())
        qset = qset.order_by('-pub_date')[:5]

        return qset

P.S.: I found a similar issue described HERE, but I'm still confused of what is actually causing such a behavior. Even though I know how to make the test working in this particular example it still important for me to understand what's going on. :)

注:我在这里发现了一个类似的问题,但我仍然搞不清究竟是什么导致了这种行为。尽管我知道如何使测试在这个特定的示例中工作,但是对我来说理解发生了什么仍然很重要。:)

1 个解决方案

#1


1

First off, as I suspect and you inspected, response.context['latest_question_list'] is a queryset, so you couldn't directly compare queryset object with list object.

首先,正如我和你检查过的,反应。context['latest_question_list']是一个queryset,所以不能直接比较queryset对象和list对象。

Also, assertQuerysetEqual is documented in django doc, quoting here:

此外,assertQuerysetEqual在django doc中有记录,这里引用:

TransactionTestCase.assertQuerysetEqual(qs, values, transform=repr, ordered=True, msg=None)

TransactionTestCase。assertQuerysetEqual(qs, values, transform=repr, ordered=True, msg=None)

The comparison of the contents of qs and values is performed using the function transform; by default, this means that the repr() of each value is compared. Any other callable can be used if repr() doesn’t provide a unique or helpful comparison.

利用函数变换对q和值的内容进行比较;默认情况下,这意味着比较每个值的repr()。如果repr()不提供唯一或有用的比较,则可以使用任何其他可调用。

You can see that the assertQuerysetEqual is comparing each value in the queryset with the list you provided, so it will loop through the whole thing and compare each one. That's why it would pass the test but fails assertEqual.

您可以看到assertQuerysetEqual正在将queryset中的每个值与您提供的列表进行比较,因此它将循环整个过程并对每个值进行比较。这就是为什么它会通过测试却失败的原因。

更多相关文章

  1. 如何将json转换为对象?
  2. Django:测试成功加载静态文件
  3. Python 全栈开发七 面向对象
  4. Python可执行对象——exec、eval、compile
  5. Appium基于Python APP自动化测试框架
  6. python-selenium-定位一组对象
  7. AttributeError:'Flask'对象没有属性'login_manager' - Login_Ma
  8. 在save方法中创建两个对象
  9. 'str'对象不能解释为groupby上的整数

随机推荐

  1. Android之父深入解析Android
  2. [置顶] android调用第三方库——第四篇—
  3. android 控件位置常用布局
  4. 流水笔记--2015-9-13
  5. Android野史系列:3.利用Android Studio开
  6. Android的简单介绍
  7. Android版本演进中的兼容性问题
  8. Ubuntu16.04下安装Android机顶盒(Android4
  9. 使用Eclipse搭建Android的开发环境
  10. Android Studio 单刷《第一行代码》系列