Abfragezählung: Grundlegende Django-Leistungstests

Hallo alle zusammen. Wir haben eine Übersetzung eines weiteren nützlichen Materials für Studenten des Kurses "Webentwickler in Python" vorbereitet , der gestern begonnen hat.





Sie können häufig Informationen zu Testmethoden wie TDD und zum Testen der Geschäftslogik einer Anwendung erhalten. Das Testen der Anwendungsleistung ist jedoch eine völlig andere Aufgabe. Es gibt viele verschiedene Möglichkeiten, aber der häufigste Ansatz besteht darin, eine Umgebung zu erstellen, in der Sie einen DDoS-Angriff auf Ihre Anwendung durchführen und deren Verhalten beobachten können. Dies ist ein sehr interessantes Thema, aber darüber möchte ich heute nicht sprechen. Heute sehen wir uns einen einfacheren Test an, den Sie mit den Standard-Django-Komponententests durchführen können: Testen Sie, wie oft Ihre Anwendung auf die Datenbank zugreift.

Das Testen ist sehr einfach, und genau dieser Aspekt kann die Anwendungsleistung in einem frühen Stadium beeinträchtigen. Dieser Aspekt ist der erste, der getestet wird, wenn etwas langsam zu arbeiten beginnt. Die gute Nachricht ist, dass Sie nur eines wissen müssen, um Tests dieser Art zu schreiben: die assertNumQueries- Methode , die recht einfach zu verwenden ist. Hier ist ein Beispiel:

from django.test import TestCase, Client
from django.urls import reverse
from trucks.models import Truck

class TrucksTestCase(TestCase):
    def test_list_trucks_view_performance(self):
        client = Client()

        Truck.objects.create(...)

        with self.assertNumQueries(6):
            response = client.get(reverse("trucks:list_trucks"))

        self.assertEqual(response.context["trucks_list"], 1)

Der obige Code besagt, dass die "trucks:list_trucks"Anwendung während der Ansicht nur sechsmal auf die Datenbank zugreift. Beachten Sie jedoch, dass wir vor dem Start zunächst ein neues Objekt erstellen Truckund anschließend sagen, dass die Kontextdaten der Ansicht trucks_listmindestens ein Objekt enthalten. Bei dieser Art von Tests ist dies wichtig, da Sie eine Garantie benötigen, dass Sie nicht an einem leeren Datensatz testen. Es ist wichtig zu verstehen, dass es Trucknicht ausreicht , nur eine Klasse zu instanziieren . Sie müssen überprüfen, ob es in den Kontext aufgenommen wurde. Möglicherweise filtern Sie die LKW-Liste, sodass Ihre Instanz wahrscheinlich Trucknicht im Ergebnis enthalten ist.

Nachdem wir all das getan haben, haben wir bereits bedeutende Fortschritte erzielt, aber es gibt noch einen weiteren wichtigen Schritt, der leicht zu vergessen ist. Wenn wir möchten, dass unsere Ansichten skaliert werden, müssen wir sicherstellen, dass die Leistung nicht abnimmt, wenn die Anzahl der zurückgegebenen Artikel steigt. Am Ende haben wir immer noch ein Leistungsproblem, wenn wir uns nicht sechsmal an die Datenbank wenden, um einen Artikel zu erhalten, sondern 106, wenn wir 100 Artikel haben. Wir benötigen eine konstante Anzahl von Datenbankaufrufen, die nicht von der Anzahl der zurückgegebenen Artikel abhängt. Glücklicherweise ist dieses Problem auch sehr einfach gelöst. Wir müssen der Datenbank ein weiteres (oder mehrere) Elemente hinzufügen und erneut die Anzahl der Treffer zählen. So wird der Test in der endgültigen Version aussehen:

from django.test import TestCase, Client
from django.urls import reverse
from trucks.models import Truck

class TrucksTestCase(TestCase):
    def test_list_trucks_view_performance(self):
        client = Client()

        Truck.objects.create(...)

        with self.assertNumQueries(6):
            response = client.get(reverse("trucks:list_trucks"))

        self.assertEqual(response.context["trucks_list"], 1)

        Truck.objects.create(...)

        with self.assertNumQueries(6):
            response = client.get(reverse("trucks:list_trucks"))

        self.assertEqual(response.context["trucks_list"], 2)

Beachten Sie, dass wir die Anzahl der im Kontext zurückgegebenen Artikel erneut überprüfen, aber beim zweiten Durchlauf erwarten wir 2 LKWs ( Truck). Der Grund für dieses Verhalten ist ähnlich wie im ersten Fall.

Das Sicherstellen einer konstanten Anzahl von Aufrufen an die Datenbank beim Hinzufügen neuer Daten hat mehr Priorität als das Sicherstellen einer kleinen Anzahl von Aufrufen im Allgemeinen.

Als letztes müssen Sie sicherstellen, dass Ihre Daten so hydratisiert wie möglich sind. Dies bedeutet, dass Sie verwandte Daten erstellen müssen, die während der Verarbeitung Ihrer Ansicht verwendet werden. Wenn Sie dies nicht tun, besteht das Risiko, dass Ihre Anwendung in der Produktion häufiger auf die Datenbank zugreift als im Test (obwohl dies möglicherweise erfolgreich ist). In unserem Beispiel mussten wir TruckDriverein Unternehmen für unsere erstellenTruck.

from trucks.models import Truck, TruckDriver
...
        truck = Truck.objects.create(...)
        TruckDriver.objects.create(name="Alex", truck=truck)

Wenn die Anzahl der Datenbankaufrufe nach Ausführung der oben beschriebenen Schritte nicht mehr konstant ist, suchen Sie nach weiteren Informationen zu den Methoden select_related und prefetch_related .

Das ist alles für heute. Ich hoffe, dass Sie ab diesem Moment zu Beginn des Projekts die Anzahl der Abfragen überprüfen, die Ihre Anwendung für die Datenbank hat. Dies nimmt nicht viel Zeit in Anspruch, verhindert jedoch Probleme, die bei der Erhöhung der Anzahl der Benutzer Ihrer Anwendung auftreten können.

Übrigens können Sie den Kurs noch fangen . Auf Wiedersehen.

All Articles