2010-02-02 10 views
27

Non ho mai scritto alcun test nella mia vita, ma mi piacerebbe iniziare a scrivere test per i miei progetti Django. Ho letto alcuni articoli sui test e ho deciso di provare a scrivere alcuni test per un'applicazione Django estremamente semplice o un inizio.Scrivere buoni test per le applicazioni Django

L'applicazione ha due punti di vista (una visualizzazione elenco, e una vista di dettaglio) e un modello con quattro campi:

class News(models.Model): 
    title = models.CharField(max_length=250) 
    content = models.TextField() 
    pub_date = models.DateTimeField(default=datetime.datetime.now) 
    slug = models.SlugField(unique=True) 

Vorrei mostrarvi il mio file tests.py e chiedere:

Ha senso?

Sto anche testando le cose giuste?

Ci sono buone pratiche che non sto seguendo, e potresti indicarmi?

mia tests.py (Contiene 11 test):

# -*- coding: utf-8 -*- 
from django.test import TestCase 
from django.test.client import Client 
from django.core.urlresolvers import reverse 
import datetime 
from someproject.myapp.models import News 

class viewTest(TestCase): 
    def setUp(self): 
     self.test_title = u'Test title: bąrekść' 
     self.test_content = u'This is a content 156' 
     self.test_slug = u'test-title-bareksc' 
     self.test_pub_date = datetime.datetime.today() 

     self.test_item = News.objects.create(
      title=self.test_title, 
      content=self.test_content, 
      slug=self.test_slug, 
      pub_date=self.test_pub_date, 
     ) 

     client = Client() 
     self.response_detail = client.get(self.test_item.get_absolute_url()) 
     self.response_index = client.get(reverse('the-list-view')) 

    def test_detail_status_code(self): 
     """ 
     HTTP status code for the detail view 
     """ 
     self.failUnlessEqual(self.response_detail.status_code, 200) 

    def test_list_status_code(self): 
     """ 
     HTTP status code for the list view 
     """ 
     self.failUnlessEqual(self.response_index.status_code, 200) 

    def test_list_numer_of_items(self): 
     self.failUnlessEqual(len(self.response_index.context['object_list']), 1)  

    def test_detail_title(self): 
     self.failUnlessEqual(self.response_detail.context['object'].title, self.test_title)  

    def test_list_title(self): 
     self.failUnlessEqual(self.response_index.context['object_list'][0].title, self.test_title) 

    def test_detail_content(self): 
     self.failUnlessEqual(self.response_detail.context['object'].content, self.test_content)  

    def test_list_content(self): 
     self.failUnlessEqual(self.response_index.context['object_list'][0].content, self.test_content) 

    def test_detail_slug(self): 
     self.failUnlessEqual(self.response_detail.context['object'].slug, self.test_slug)  

    def test_list_slug(self): 
     self.failUnlessEqual(self.response_index.context['object_list'][0].slug, self.test_slug) 

    def test_detail_template(self): 
     self.assertContains(self.response_detail, self.test_title) 
     self.assertContains(self.response_detail, self.test_content) 

    def test_list_template(self):  
     self.assertContains(self.response_index, self.test_title) 

risposta

18

io non sono perfetto in fase di test, ma alcune riflessioni:

In sostanza è necessario verificare ogni funzione, metodo, classe qualunque cosa tu abbia scritto da solo

Ciò implica che non è necessario testare funzioni, classi, ecc. Fornite dal framework.

Detto questo, un rapido controllo delle vostre funzioni di test:

  • test_detail_status_code e test_list_status_code:
    OK per verificare se si è configurato il instradamento correttamente o meno. Ancora più importante quando fornisci la tua implementazione di get_absolute_url().

  • test_list_numer_of_items:
    OK se un determinato numero di elementi deve essere restituito dalla vista. Non necessario se il numero non è importante (cioè arbitrario).

  • test_detail_template e test_list_template:
    OK per verificare se le variabili del modello vengono impostate correttamente.

  • Tutte le altre funzioni: Non necessario.
    Ciò che stai testando qui è se l'ORM ha funzionato correttamente, se gli elenchi funzionano come previsto e se è possibile accedere (o meno) alle proprietà degli oggetti. Finché non si modifica ad es. il metodo save() di un modello e/o fornisce la logica personalizzata, non lo testerei. Dovresti fidarti degli sviluppatori di framework che questo funziona correttamente.

Dovresti solo testare ciò che hai (sopra) scritto.

Le classi modello sono forse un caso speciale. Fondamentalmente devi testarli, come ho detto, se fornisci una logica personalizzata. Ma dovresti anche testarli in base alle tue esigenze. Per esempio. potrebbe essere che un campo non può essere null (o che deve essere un determinato tipo di dati, come intero). Pertanto, è necessario verificare che la memorizzazione di un oggetto non riesca, se ha un valore null in questo campo.
Questo è non testare l'ORM per seguire correttamente le specifiche ma verificare che le specifiche soddisfino ancora i requisiti. Potrebbe essere che tu cambi il modello e cambi alcune impostazioni (casualmente o perché ti sei dimenticato dei requisiti).
Ma non è necessario testare ad es. metodi come save() o se è possibile accedere a una proprietà.

Ovviamente quando si utilizza il codice di terze parti buggy ... beh, le cose possono essere diverse. Ma poiché Django utilizza la stessa infrastruttura di test per verificare che tutto funzioni, suppongo che funzioni.

Per riassumere:
prova contro le vostre esigenze, testare il proprio codice.

Questo è solo il mio punto di vista. Forse altri hanno proposte migliori.

5

Rompi i test in due tipi completamente separati.

  • Test modello. Inseriscili nel tuo file models.py con il tuo modello. Questi test eserciteranno i metodi nelle classi modello. Puoi fare semplici CRUD (Crea, Recupera, Aggiorna, Cancella) per provare semplicemente che il tuo modello funziona. Non testare tutti gli attributi. Provate le impostazioni predefinite del campo di prova e le regole save() se siete curiosi.

    Per l'esempio, creare una classe TestNews che crea, ottiene, aggiorna ed elimina un elemento News. Assicurati di testare i risultati della data di default. Questa classe dovrebbe essere breve e al punto. È possibile, se richiesto dalla propria applicazione, testare vari tipi di elaborazione dei filtri. Il codice di test dell'unità può (e dovrebbe) fornire esempi del modo "giusto" per filtrare News.

  • Test UI. Inseriscili in un file tests.py separato. Questi test testeranno le funzioni e i modelli di visualizzazione.

    • Denominare il TestCase con la "condizione" che si sta creando. "TestNotLoggedIn". "TestLoggedIn". "TestNoValidThis". "TestNotAllowedToDoThat". Il tuo setUp eseguirà l'accesso e qualsiasi altra procedura richiesta per stabilire la condizione richiesta.

    • Nome di ciascun metodo di prova con l'azione e il risultato. "test_get_noquery_should_list", "test_post_should_validate_with_errors", "test_get_query_should_detail".

Problemi correlati