2012-02-27 17 views
15

Secondo la documentazione:Django quando utilizzare metodo teardown

A TestCase, d'altra parte, non tronca tavoli e ricaricare dati iniziali, all'inizio di un test. Al contrario, include il codice di prova in una transazione del database che viene ripristinato alla fine del test . Impedisce inoltre che il codice in prova emetta qualsiasi operazione di commit o operazioni di rollback sul database, per garantire che il rollback alla fine del test ripristini il database al suo stato iniziale alla . In ordine per garantire che tutto il codice TestCase inizi con un database pulito , il runner di prova di Django esegue tutti i test di TestCase prima di eventuali altri test (ad esempio doctest) che possono alterare il database senza ripristinandolo allo stato originale.

Quindi, se ho un test che assomiglia a questo:

class GeneralUserCreateTest(TestCase): 

    def setUp(self): 
     create_roletypes() 
     create_permissiontypes() 
     self.client = Client() 
     self.event = create_event() 

    def test_create(self): 
     create_url = reverse('event_user_signup', args=[self.event.slug]) 

     post_data = { 
      'signup-account-email': '[email protected]', 
      'signup-account-password': 'foobar', 
      'signup-account-password2': 'foobar', 
      'signup-account-first_name': 'Foo', 
      'signup-account-last_name': 'Bar', 
     } 
     response = self.client.post(create_url, data=post_data) 
     self.assertEqual(response.status_code, 302) 

     # check creation of user object 
     self.assertEqual(User.objects.filter(email=post_data['signup-account-email']).count(), 1) 
     user = User.objects.get(username=post_data['signup-account-email']) 

     # user and profile objects created 
     self.assertEqual(User.objects.all().count(), 1) 
     self.assertEqual(Profile.objects.all().count(), 1) 

     # get the first user and profile object to test against submitted field 
     user = User.objects.all()[0] 
     profile = Profile.objects.all()[0] 
     role = Role.objects.filter(event=self.event, profiles=profile)[0] 
     self.assertEqual(role.roletype.name, 'General') 
     self.assertEqual(user.username, post_data['signup-account-email']) 
     self.assertEqual(user.email, post_data['signup-account-email']) 
     self.assertEqual(profile.first_name, post_data['signup-account-first_name']) 
     self.assertEqual(profile.last_name, post_data['signup-account-last_name']) 

è ancora necessario eseguire un metodo teardown o fa la classe TestCase prendersi cura di esso? In tal caso, quando si dovrebbe utilizzare il metodo teardown data la disponibilità della classe TestCase?

risposta

22

Per gli scopi del database, tearDown è praticamente inutile, poiché ogni test viene eseguito in una transazione. Tuttavia, non tutto in un test coinvolge il database. Potresti testare la creazione/lettura dei file, i processi di spin-off, le connessioni di rete aperte, ecc. Questi tipi di cose di solito richiedono di "chiuderli" dopo aver finito. Questo è lo scopo di tearDown, ovvero la pulizia di materiale dal tuo metodo setUp, non correlato al database. (Anche se in realtà ti stai connettendo direttamente ad un database, cioè come i veri test di Django devono fare per assicurarti che tutta la roba DBAPI funzioni correttamente, dovresti fare anche la pulizia.)

5

Se sei utilizzando un database alternativo come MongoDB o Redis ed è necessario caricare in una serie di dati iniziali (una "raccolta"), sarà necessario sovrascrivere anche il metodo tearDown.

Vedi http://www.belchak.com/2011/02/07/unit-testing-django-with-a-nosql-backend/

In generale, django.test.TestCase fa un colore completo del database all'inizio di ogni nuovo test. Ciò significa che non abbiamo bisogno di cancellare manualmente gli oggetti nel nostro TearDown come Chris Pratt ha menzionato sopra. Il prossimo set-up di test assicurerà che il database sia pulito.

Tuttavia, se si utilizzano i doctest e unittest.TestCase, non verrà eseguito il flush del database prima dell'esecuzione dei test. All'inizio di un test, il database si troverà in qualsiasi stato del precedente test rimasto. Ciò significa che qualsiasi dato vagante lasciato da una corsa precedente causerebbe conflitto. Quindi, se stiamo usando doctest o unittest.TestCase per i nostri test di django, una pulizia potrebbe essere una buona pratica.

Infine, in scenari più complicati, potrebbe anche avere senso persodire volutamente il database di test per individuare specifici bug di test dell'unità.

8

Stavo lavorando a un progetto che gestiva alcuni caricamenti di file e avevo bisogno di eliminare i file creati dal test e il metodo tearDown era molto utile in quella situazione.

import shutil 

#.... 
#.... 

    def tearDown(self): 
     shutil.rmtree(settings.UPLOAD_ROOT) 
Problemi correlati