2013-07-16 17 views
13

Sto provando a testare le mie vedute di Django. Questo punto di vista passa un QuerySet al modello:Come posso testare le Query di Django?

def merchant_home(request, slug): 
    merchant = Merchant.objects.get(slug=slug) 
    product_list = merchant.products.all() 
    return render_to_response('merchant_home.html', 
          {'merchant': merchant, 
          'product_list': product_list}, 
          context_instance=RequestContext(request)) 

e test:

def test(self): 
    "Merchant home view should send merchant and merchant products to the template" 
    merchant = Merchant.objects.create(name='test merchant') 
    product = Product.objects.create(name='test product', price=100.00) 
    merchant.products.add(product) 

    test_client = Client() 
    response = test_client.get('/' + merchant.slug) 
    # self.assertListEqual(response.context['product_list'], merchant.products.all()) 
    self.assertQuerysetEqual(response.context['product_list'], merchant.products.all()) 

EDIT Sto usando self.assertQuerysetEqual invece di self.assertListEqual. Purtroppo questo ancora non funziona, e il terminale visualizza questo: ['<Product: Product object>'] != [<Product: Product object>]


assertListEqual solleva: oggetto 'QuerySet' non ha un attributo 'differenza' assertEqual non funziona, anche se self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0]) fa passaggio.

Suppongo che ciò sia dovuto al fatto che i QuerySet sono oggetti diversi anche se contengono le stesse istanze del modello.

Come verificare che due set di query contengano gli stessi dati? Lo sto testando correttamente? Questo è il mio quarto giorno di apprendimento di Django, quindi mi piacerebbe conoscere le migliori pratiche se possibile. Grazie.

risposta

15

Utilizzare assertQuerysetEqual, che è stato creato per confrontare i due set di query. Sarà necessario creare sottoclasse di Django django.test.TestCase affinché sia ​​disponibile nei test.

+6

Impressionante, questo è utile, anche se ora il mio test non riesce a causa di questo: AssertionError: [ '< Prodotto: Oggetto prodotto> ']! = [] L'unica differenza che vedo è che esistono virgolette attorno al primo oggetto prodotto. Sono entrambi di classe QuerySet – jz999

+0

Aggiorna la tua domanda con il nuovo codice di test. :) – girasquid

+0

Ho appena fatto, grazie – jz999

5

Ho appena avuto lo stesso problema. Il secondo argomento di assertQuerysetEqual deve essere un elenco dei possibili repr() s come stringhe. Ecco un esempio dalla suite di test Django:

self.assertQuerysetEqual(c1.tags.all(), ["<Tag: t1>", "<Tag: t2>"], ordered=False) 
+1

Vedere http://stackoverflow.com/a/14189017/678486 (completo divulgazione questa è la mia risposta). –

1

Un'alternativa, ma non necessariamente migliore, metodo potrebbe assomigliare a questo (contesto test in vista, ad esempio) quando si usa pytest:

all_the_things = Things.objects.all() 
assert set(list(response.context_data['all_the_things'])) == set(list(all_the_things)) 

Questo lo converte in un elenco, quindi in un set, che è direttamente confrontabile con un altro set. Prestare attenzione al comportamento di set, tuttavia, potrebbe non essere esattamente ciò che si desidera in quanto rimuoverà i duplicati.

1

Per impostazione predefinita, assertQuerysetEqual utilizza repr() sul primo argomento, motivo per cui si sono verificati problemi con le stringhe nel confronto tra i queryset.

Per risolvere questo problema, è possibile override the transform argument con una funzione lambda che non utilizza repr():

self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x) 
Problemi correlati