Recuento de consultas: pruebas de rendimiento básicas de Django

Hola a todos. Hemos preparado una traducción de otro material útil para los estudiantes del curso "Desarrollador web en Python" , que comenzó ayer.





A menudo puede escuchar sobre métodos de prueba como TDD y cómo probar la lógica de negocios de una aplicación. Sin embargo, probar el rendimiento de la aplicación es una tarea completamente diferente. Hay muchas formas diferentes, pero el enfoque más común es crear un entorno en el que pueda realizar un ataque DDoS en su aplicación y observar su comportamiento. Este es un tema muy interesante, pero no es de lo que quiero hablar hoy. Hoy veremos una prueba más simple, una que puede hacer usando las pruebas unitarias Django predeterminadas: es decir, probar la cantidad de veces que su aplicación accede a la base de datos.

Probar esto es muy simple, y este es exactamente el aspecto que puede dañar el rendimiento de la aplicación en las primeras etapas. Este aspecto es el primero en probarse cuando algo comienza a funcionar lentamente. La buena noticia es que solo hay una cosa que necesita saber para escribir pruebas de este tipo: el método ClaimNumQueries , y es bastante fácil de usar. Aquí hay un ejemplo:

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)

El código anterior afirma que durante la vista, la "trucks:list_trucks"aplicación accederá a la base de datos solo 6 veces. Pero hay algo más, tenga en cuenta que antes de comenzar, primero creamos un nuevo objeto Truck, y después de eso decimos que trucks_listhay al menos un objeto en los datos de contexto de la vista . En este tipo de pruebas, esto es importante, porque necesita una garantía de que no está probando en un conjunto de datos vacío. Es importante comprender que simplemente crear instancias de una clase Truckno es suficiente. Debe verificar si se ha incluido en el contexto. Quizás esté filtrando la lista de camiones, por lo que es probable que su instancia Truckno se incluya en el resultado.

Habiendo hecho todo lo anterior, ya hemos logrado un progreso significativo, pero hay otro paso importante que es fácil de olvidar. Si queremos que nuestras vistas se escalen, debemos asegurarnos de que el rendimiento no disminuya a medida que aumenta el número de artículos devueltos. Al final, todavía tenemos un problema de rendimiento si recurrimos a la base de datos no 6 veces para obtener un elemento, sino 106 si tenemos 100 elementos. Necesitamos un número constante de llamadas a la base de datos, que no dependerá del número de artículos devueltos. Afortunadamente, este problema también se resuelve de manera muy simple, necesitamos agregar uno más (o varios) elementos a la base de datos y nuevamente contar el número de visitas. Así se verá la prueba en la versión final:

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)

Tenga en cuenta que nuevamente verificamos el número de artículos devueltos en el contexto, pero en la segunda ejecución esperamos 2 camiones ( Truck). La razón de este comportamiento es similar al primer caso.

Asegurar un número constante de llamadas a la base de datos al agregar nuevos datos es más prioritario que garantizar un pequeño número de llamadas en general.

Lo último que debe hacer es asegurarse de que sus datos estén lo más hidratados posible. Esto significa que debe crear datos relacionados que se utilizarán durante el procesamiento de su vista. Si no lo hace, existe el riesgo de que su aplicación acceda a la base de datos con más frecuencia en producción que en la prueba (aunque puede tener éxito). En nuestro ejemplo, necesitábamos crear TruckDriveruna empresa para nuestroTruck.

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

Si el número de llamadas a la base de datos ya no es constante después de realizar los pasos descritos anteriormente, busque más información sobre los métodos select_related y prefetch_related .

Eso es todo por hoy, espero que a partir de este momento comience a verificar el número de consultas de su aplicación a la base de datos al comienzo del proyecto. Esto no llevará mucho tiempo, pero evitará los problemas que puedan surgir con el aumento en el número de usuarios de su aplicación.

Por cierto, todavía puedes tomar el curso . Nos vemos.

All Articles