Wie soll ich Tests für Formulare in Django schreiben?


109

Ich möchte Anfragen an meine Ansichten in Django simulieren, wenn ich Tests schreibe. Dies dient hauptsächlich zum Testen der Formulare. Hier ist ein Ausschnitt einer einfachen Testanfrage:

from django.tests import TestCase

class MyTests(TestCase):
    def test_forms(self):
        response = self.client.post("/my/form/", {'something':'something'})
        self.assertEqual(response.status_code, 200) # we get our page back with an error

Die Seite gibt immer eine Antwort von 200 zurück, unabhängig davon, ob ein Formularfehler vorliegt oder nicht. Wie kann ich überprüfen, ob mein Formular fehlgeschlagen ist und ob in dem bestimmten Feld ( soemthing) ein Fehler aufgetreten ist?

Antworten:


250

Ich denke, wenn Sie nur das Formular testen möchten, sollten Sie nur das Formular testen und nicht die Ansicht, in der das Formular gerendert wird. Beispiel, um sich ein Bild zu machen:

from django.test import TestCase
from myapp.forms import MyForm

class MyTests(TestCase):
    def test_forms(self):
        form_data = {'something': 'something'}
        form = MyForm(data=form_data)
        self.assertTrue(form.is_valid())
        ... # other tests relating forms, for example checking the form data

62
+1. Die Idee von Unit- Tests besteht darin, jede Einheit einzeln zu testen.
Daniel Roseman

13
@ Daniel Aber Integrationstests sind viel nützlicher und es ist wahrscheinlicher, dass sie Fehler erkennen.
Wobbily_col

19
@wobbily_col Es dauert auch länger, den tatsächlichen Fehler in einem Integrationstest zu erkennen. In einem Unit-Test ist es offensichtlicher. Ich denke, für eine gute Testabdeckung brauchen Sie trotzdem beide.
Torsten Engelbrecht

11
So überprüfen Sie auf einen bestimmten Formularfehler:self.assertEquals(form.errors['recipient'], [u"That recipient isn't valid"])
Emil Stenström

18
self.assertEqual(form.is_valid(), True)könnte vereinfacht werden:self.assertTrue(form.is_valid())
Adam Taylor

76

https://docs.djangoproject.com/de/stable/topics/testing/tools/#django.test.SimpleTestCase.assertFormError

from django.tests import TestCase

class MyTests(TestCase):
    def test_forms(self):
        response = self.client.post("/my/form/", {'something':'something'})
        self.assertFormError(response, 'form', 'something', 'This field is required.')

Wobei "Formular" der Name der Kontextvariablen für Ihr Formular ist, "etwas" der Feldname und "Dieses Feld ist erforderlich". ist der genaue Text des erwarteten Validierungsfehlers.


Dies löst einen AttibuteError für mich aus: AttributeError: 'SafeUnicode'-Objekt hat kein Attribut' Fehler '
sbaechler

Für Anfänger: Erstellen Sie vorher einen Benutzer und verwenden Sie ihn self.client.force_login(self.user)als erste Zeile in der Testmethode.
Sgauri

Ich hatte ein Problem mit diesem Beitrag (), dann stellte ich fest, dass ich ihn als mehrteilig senden musste, wie folgt: response = self.client.post ("/ form-url /", data = {'name': 'test123' , 'category': 1, 'note': 'note123'}, content_type = django.test.client.MULTIPART_CONTENT) Wenn beim Speichern des Formulars keine leere Instanz mehr vorhanden ist, überprüfen Sie die vom Browser gesendeten Anforderungen
Ghaleb Khaled,

17

Die ursprüngliche Antwort von 2011 war

self.assertContains(response, "Invalid message here", 1, 200)

Aber ich sehe jetzt (2018), dass es eine ganze Menge anwendbarer Behauptungen gibt :

  • assertRaisesMessage
  • assertFieldOutput
  • assertFormError
  • assertFormsetError

Treffen Sie Ihre Wahl.


+1 Dies hat bei mir funktioniert, als es sich um einen allgemeinen Formularfehler handelte, der nicht an ein Feld angehängt wird.
Aaron Lelevier
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.