Python 3.4 AssertEqual() unpredicted behavior when using in a Django unit test
Question: 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** :

> line 113, in test_index_view_with_questions_without_choices
> self.assertEqual(response.context['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:

    
    
    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](http://stackoverflow.com/questions/13078885/django-assertequals-test-
failing-even-though-answer-is-equal), 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. :)


Answer: 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.

Also, `assertQuerysetEqual` is documented in [django
doc](https://docs.djangoproject.com/en/1.9/topics/testing/tools/#django.test.TransactionTestCase.assertQuerysetEqual),
quoting here:

> 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.

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`.

