Tutorial

Hinzufügen von Unit-Tests zu Ihrem Django-Projekt

PythonDjangoPython FrameworksApplicationsDevelopmentProgramming Project

Der Autor hat den Open Internet/Free Speech Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

Einführung

Es ist fast unmöglich, Websites zu erstellen, die beim ersten Mal perfekt und fehlerfrei funktionieren. Aus diesem Grund müssen Sie Ihre Webanwendung testen, um diese Fehler zu finden und proaktiv zu bearbeiten. Um die Effizienz von Tests zu verbessern, ist es üblich, Tests in Einheiten zu unterteilen, die bestimmte Funktionen der Webanwendung testen. Diese Praxis wird als Unit-Test bezeichnet. Es erleichtert das Erkennen von Fehlern, da sich die Tests unabhängig von anderen Teilen auf kleine Teile (Units) Ihres Projekts konzentrieren.

Das Testen einer Website kann eine komplexe Aufgabe sein, da sie aus mehreren Logikebenen besteht, z. B. der Verarbeitung von HTTP-Anforderungen, der Formularvalidierung und dem Wiedergeben von Vorlagen. Django bietet jedoch eine Reihe von Tools, mit denen Sie Ihre Webanwendung nahtlos testen können. In Django ist die bevorzugte Methode zum Schreiben von Tests die Verwendung des Python-Moduls unittest, obwohl andere Test-Frameworks verwendet werden können.

In diesem Tutorial richten Sie eine Testsuite in Ihrem Django-Projekt ein und schreiben Unit-Tests für die Modelle und Ansichten in Ihrer Anwendung. Sie führen diese Tests durch, analysieren ihre Ergebnisse und erfahren, wie Sie die Ursachen für fehlgeschlagene Tests ermitteln.

Voraussetzungen

Bevor Sie mit diesem Tutorial beginnen, benötigen Sie Folgendes:

Schritt 1 - Hinzufügen einer Testsuite zu Ihrer Django-Anwendung

Eine Testsuite in Django ist eine Sammlung aller Testfälle in allen Anwendungen in Ihrem Projekt. Damit das Django-Testdienstprogramm die vorhandenen Testfälle ermitteln kann, schreiben Sie die Testfälle in Skripts, deren Namen mit test beginnen. In diesem Schritt erstellen Sie die Verzeichnisstruktur und die Dateien für Ihre Testsuite und erstellen darin einen leeren Testfall.

Wenn Sie der Django-Entwicklungs-Tutorial-Reihe gefolgt sind, haben Sie eine Django-App namens blogsite.

Erstellen wir einen Ordner für alle unsere Testskripte. Aktivieren Sie zunächst die virtuelle Umgebung:

  • cd ~/my_blog_app
  • . env/bin/activate

Navigieren Sie dann zum App-Verzeichnis blogsite, dem Ordner, der die Dateien models.py und views.py enthält, und erstellen Sie einen neuen Ordner mit dem Namen tests:

  • cd ~/my_blog_app/blog/blogsite
  • mkdir tests

Als nächstes verwandeln Sie diesen Ordner in ein Python-Paket. Fügen Sie also eine __init__.py-Datei hinzu:

  • cd ~/my_blog_app/blog/blogsite/tests
  • touch __init__.py

Jetzt fügen Sie eine Datei zum Testen Ihrer Modelle und eine weitere zum Testen Ihrer Ansichten hinzu:

  • touch test_models.py
  • touch test_views.py

Schließlich erstellen Sie einen leeren Testfall in test_models.py. Sie müssen die Django TestCase-Klasse importieren und sie zu einer Superklasse Ihrer eigenen Testfallklasse machen. Später werden Sie diesem Testfall Methoden hinzufügen, um die Logik in Ihren Modellen zu testen. Öffnen Sie die Datei test_models.py:

  • nano test_models.py

Fügen Sie den folgenden Code zur Datei hinzu:

~/my_blog_app/blog/blogsite/tests/test_models.py
from django.test import TestCase

class ModelsTestCase(TestCase):
    pass

Sie haben der blogsite-App jetzt erfolgreich eine Testsuite hinzugefügt. Als nächstes füllen Sie die Details des leeren Modell-Testfalls aus, den Sie hier erstellt haben.

Schritt 2 - Testen Ihres Python-Codes

In diesem Schritt testen Sie die Logik des in die Datei models.py geschriebenen Codes. Insbesondere testen Sie die Methode save des Modells Post, um sicherzustellen, dass es beim Aufruf den korrekten Slug des Titels eines Posts erzeugt.

Schauen wir uns zunächst den Code an, den Sie bereits in Ihrer Datei models.py für die Methode save des Post-Modells haben:

  • cd ~/my_blog_app/blog/blogsite
  • nano models.py

Sie sehen dann Folgendes:

~/my_blog_app/blog/blogsite/models.py
class Post(models.Model):
    ...
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)
    ...

Wir können sehen, dass überprüft wird, ob der zu speichernde Beitrag einen Slug-Wert hat, und wenn nicht, wird slugify aufgerufen, um einen Slug-Wert dafür zu erstellen. Dies ist die Art von Logik, die Sie möglicherweise testen möchten, um sicherzustellen, dass beim Speichern eines Beitrags tatsächlich Slugs erstellt werden.

Schließen Sie die Datei.

Gehen Sie zum Testen zu test_models.py zurück:

  • nano test_models.py

Aktualisieren Sie sie dann wie folgt und fügen Sie die hervorgehobenen Abschnitte hinzu:

~/my_blog_app/blog/blogsite/tests/test_models.py
from django.test import TestCase
from django.template.defaultfilters import slugify
from blogsite.models import Post


class ModelsTestCase(TestCase):
    def test_post_has_slug(self):
        """Posts are given slugs correctly when saving"""
        post = Post.objects.create(title="My first post")

        post.author = "John Doe"
        post.save()
        self.assertEqual(post.slug, slugify(post.title))

Diese neue Methode test_post_has_slug erstellt einen neuen Beitrag mit dem Titel „My first post“, gibt dem Beitrag einen Autor und speichert ihn. Anschließend wird mithilfe der assertEqual-Methode aus dem Python unittest-Modul überprüft, ob der Slug für den Beitrag korrekt ist. Die assertEqual-Methode prüft, ob die beiden an sie übergebenen Argumente gleich sind, wie durch den Operator "==" festgelegt, und löst einen Fehler aus, wenn dies nicht der Fall ist.

Speichern und schließen Sie test_models.py.

Das ist ein Beispiel dafür, was getestet werden kann. Je mehr Logik Sie Ihrem Projekt hinzufügen, desto mehr gibt es zu testen. Wenn Sie der Methode save mehr Logik hinzufügen oder neue Methoden für das Post-Modell erstellen, sollten Sie hier weitere Tests hinzufügen. Sie können sie der Methode test_post_has_slug hinzufügen oder neue Testmethoden erstellen, ihre Namen müssen jedoch mit test beginnen.

Sie haben erfolgreich einen Testfall für das Post-Modell erstellt, in dem Sie bestätigt haben, dass Slugs nach dem Speichern korrekt erstellt wurden. Im nächsten Schritt schreiben Sie einen Testfall, der Ansichten testen soll.

Schritt 3 - Verwenden des Testclients von Django

In diesem Schritt schreiben Sie einen Testfall, der eine Ansicht mit dem Django-Testclient testet. Der Testclient ist eine Python-Klasse, die als Dummy-Webbrowser fungiert und es Ihnen ermöglicht, Ihre Ansichten zu testen und mit Ihrer Django-Anwendung auf die gleiche Weise wie ein Benutzer zu interagieren. Sie können auf den Testclient zugreifen, indem Sie in Ihren Testmethoden auf self.client verweisen. Lassen Sie uns beispielsweise einen Testfall in test_views.py erstellen. Öffnen Sie als erstes die Datei test_views.py:

  • nano test_views.py

Fügen Sie Folgendes hinzu:

~/my_blog_app/blog/blogsite/tests/test_views.py
from django.test import TestCase


class ViewsTestCase(TestCase):
    def test_index_loads_properly(self):
        """The index page loads properly"""
        response = self.client.get('your_server_ip:8000')
        self.assertEqual(response.status_code, 200)

Der ViewsTestCase enthält eine test_index_loads_properly-Methode, die den Django-Testclient verwendet, um die Indexseite der Website zu besuchen (http://your_server_ip:8000, wobei your_server_ip die IP-Adresse des Servers ist, den Sie benutzen). Anschließend prüft die Testmethode, ob die Antwort den Statuscode 200 hat, was bedeutet, dass die Seite fehlerfrei geantwortet hat. Infolgedessen können Sie sicher sein, dass die Seite auch beim Besuch des Benutzers fehlerfrei reagiert.

Abgesehen vom Statuscode können Sie sich auf der Seite Testing Response der Django-Dokumentation über weitere Eigenschaften der Testclient-Antwort informieren, die Sie testen können.

In diesem Schritt haben Sie einen Testfall erstellt, um zu testen, ob die Ansicht, in der die Indexseite wiedergegeben wird, fehlerfrei funktioniert. In Ihrer Testsuite befinden sich jetzt zwei Testfälle. Im nächsten Schritt führen Sie diese aus, um ihre Ergebnisse zu sehen.

Schritt 4 - Ausführen Ihrer Tests

Nachdem Sie eine Testsuite für das Projekt erstellt haben, ist es an der Zeit, diese Tests auszuführen und ihre Ergebnisse anzuzeigen. Navigieren Sie zum Ausführen der Tests zum Ordner blog (der die Datei manage.py der Anwendung enthält):

  • cd ~/my_blog_app/blog

Führen Sie sie dann folgendermaßen aus:

  • python manage.py test

In Ihrem Terminal wird eine Ausgabe ähnlich der folgenden angezeigt:

Output
Creating test database for alias 'default'... System check identified no issues (0 silenced). .. ---------------------------------------------------------------------- Ran 2 tests in 0.007s OK Destroying test database for alias 'default'...

In dieser Ausgabe gibt es zwei Punkte .., von denen jeder einen bestandenen Testfall darstellt. Jetzt ändern Sie test_views.py, um einen fehlgeschlagenen Test auszulösen. Öffnen Sie zuerst die Datei mit:

  • nano test_views.py

Ändern Sie dann den markierten Code zu:

~/my_blog_app/blog/blogsite/tests/test_views.py
from django.test import TestCase


class ViewsTestCase(TestCase):
    def test_index_loads_properly(self):
        """The index page loads properly"""
        response = self.client.get('your_server_ip:8000')
        self.assertEqual(response.status_code, 404)

Hier haben Sie den Statuscode von 200 auf 404 geändert. Führen Sie nun den Test erneut aus Ihrem Verzeichnis mit manage.py aus:

  • python manage.py test

Sie sehen die folgende Ausgabe:

Output
Creating test database for alias 'default'... System check identified no issues (0 silenced). .F ====================================================================== FAIL: test_index_loads_properly (blogsite.tests.test_views.ViewsTestCase) The index page loads properly ---------------------------------------------------------------------- Traceback (most recent call last): File "~/my_blog_app/blog/blogsite/tests/test_views.py", line 8, in test_index_loads_properly self.assertEqual(response.status_code, 404) AssertionError: 200 != 404 ---------------------------------------------------------------------- Ran 2 tests in 0.007s FAILED (failures=1) Destroying test database for alias 'default'...

Sie sehen, dass es eine beschreibende Fehlermeldung gibt, die Sie über das Skript, den Testfall und die Methode informiert, die fehlgeschlagen sind. Außerdem wird die Fehlerursache angezeigt, wobei der Statuscode in diesem Fall nicht gleich 404 ist, mit der Meldung AssertionError: 200! = 404. Der AssertionError wird hier in der hervorgehobenen Codezeile in der Datei test_views.py ausgelöst:

~/my_blog_app/blog/blogsite/tests/test_views.py
from django.test import TestCase


class ViewsTestCase(TestCase):
    def test_index_loads_properly(self):
        """The index page loads properly"""
        response = self.client.get('your_server_ip:8000')
        self.assertEqual(response.status_code, 404)

Er zeigt Ihnen, dass die Behauptung falsch ist, d. h. der Antwortstatuscode (200) entspricht nicht den Erwartungen (404). Vor der Fehlermeldung können Sie sehen, dass sich die beiden Punkte .. jetzt in . F geändert haben, was Ihnen sagt, dass der erste Testfall bestanden wurde, während der zweite nicht bestanden hat.

Zusammenfassung

In diesem Tutorial haben Sie in Ihrem Django-Projekt eine Testsuite erstellt, Testfälle zum Testen des Modells und zur Ansichtslogik hinzugefügt, das Ausführen von Tests gelernt und die Testausgabe analysiert. Als nächsten Schritt können Sie neue Testskripte für Python-Code erstellen, der nicht in models.py und views.py enthalten ist.

Im Folgenden finden Sie einige Artikel, die sich beim Erstellen und Testen von Websites mit Django als hilfreich erweisen können:

Weitere Tutorials und Projekte finden Sie auf unserer Django-Themenseite.

Creative Commons License