2016-01-06 60 views
2

我在Django單元測試(Python 3.4)中遇到了AssertEquals()的一些奇怪行爲。下面的測試結果在斷言錯誤這樣Python 3.4 AssertEqual()在Django單元測試中使用時的不可預測行爲

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

下面是測試本身:

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'], []) 

更改最後一行,像這樣:

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

使測試工作正常但我無法得到它的原因拒絕與清單本身一起工作。

我也有同樣的應用程序和項目非常類似的測試,它工作得很好

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'], []) 

這裏的視圖本身以顯示查詢集是如何定義的:

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 

PS:我發現了一個類似的問題描述HERE,但我仍然困惑什麼是真正導致這樣的一種行爲。儘管我知道如何使這個測試在這個特定的例子中起作用,但對於我理解發生的事情仍然很重要。 :)

回答

1

首先,我懷疑和你檢查,response.context['latest_question_list']是一個查詢集,所以你不能直接比較queryset對象與列表對象。

此外,assertQuerysetEqualdjango doc進行了說明,引用在這裏:

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.

你可以看到assertQuerysetEqual是與您提供的列表中查詢集的每個值進行比較,所以它會在整個事情循環,比較每一個。這就是爲什麼它會通過測試,但失敗了assertEqual

+0

謝謝你的回覆!我自己也檢查過它..所以response.context ['some key']我們實際訪問的是一個QuerySet本身,並且有類型django.db.models.query.QuerySet,所以它不是一個列表。但是如何解釋其他測試工作正常?它也包含行:** self.assertQuerysetEqual(response.context ['lastest_question_list'],[])**,但在這種情況下,它的工作原理..差異在哪裏? – sancau

+0

我更新了我的答案。檢查這個問題上的答案以及:http://stackoverflow.com/questions/11610943/django-1-4-assertquerysetequal-how-to-use-method?answertab=votes#tab-top –

+0

非常有幫助,謝謝! – sancau

相關問題