- ¿Qué son las pruebas de integración?
- Primer ejemplo: Listar usuarios
- Verificar el contenido
- Cómo ejecutar los tests
- Trabajando con la base de datos
- Cargar muchos datos con fixtures
Vamos a aprender a comprobar que nuestra aplicación con Django realmente funciona. Ya hemos avanzado bastante en el curso, así que es un buen momento para introducir las pruebas de integración, es decir, verificar que la app funciona "como lo haría un usuario". Lo haremos paso a paso, de forma sencilla.
¿Qué son las pruebas de integración?
En Django no necesitamos un servidor encendido para esto: usamos una herramienta llamada client, que simula solicitudes internas rápidas.
Primer ejemplo: Listar usuarios
Supongamos que tenemos un sitio con un recurso en la URL /users/ donde se lista un grupo de usuarios registrados. Vamos a escribir un test para verificar que este recurso funciona.
Esta es la estructura básica de archivos para una app llamada users dentro de un proyecto:
.
├── manage.py
└── simple_blog
├── users
│ ├── models.py
│ ├── views.py
│ ├── urls.py
│ ├── tests.py
Código del test
📁 Archivo: users/tests.py
from django.test import TestCase
from django.urls import reverse
class UsersTest(TestCase):
def test_users_list(self):
# Simulamos una solicitud GET a la ruta "users:index"
response = self.client.get(reverse("users:index"))
# Verificamos que la respuesta tenga estado 200 (OK)
self.assertEqual(response.status_code, 200)
¿Qué está pasando aquí?
- Usamos
reverse("users:index")para obtener la URL con nombreusers:index. - El método
self.client.get()simula una solicitud GET. - Luego usamos
assertEqual()para asegurarnos que la respuesta fue 200, lo cual significa "todo bien".
❗ Pero ojo, eso no nos dice que el contenido sea correcto… solo que hubo respuesta.
Verificar el contenido
Si esperas que se muestre una lista de usuarios, tienes que verificar eso también.
def test_users_list(self):
response = self.client.get(reverse("users:index"))
self.assertEqual(response.status_code, 200)
# Verificamos que haya 'users' dentro del contexto
self.assertIn('users', response.context)
# Verificamos que la lista no esté vacía
users = response.context['users']
self.assertTrue(len(users) > 0)
Con estas líneas, estamos verificando que la vista devolvió una lista de usuarios y que esa lista no está vacía.
Cómo ejecutar los tests
Desde la terminal:
uv run manage.py test
Eso:
- Crea una base de datos temporal de prueba
- Corre todos los tests
- Borra la base temporal al terminar
Trabajando con la base de datos
Ahora vamos a un ejemplo más interesante: actualizar datos. Pero, para probarlo necesitamos crear datos de prueba antes. Django se encarga de que cada test sea aislado: crea datos y luego los borra automáticamente.
Podemos usar el método especial setUp() para preparar los datos previos:
from django.test import TestCase
from django.urls import reverse
from .models import Users
class UsersTest(TestCase):
def setUp(self):
# Creamos un usuario en la base de datos para luego modificarlo
self.user = Users.objects.create(name="John", email="johndoe@mail.com")
def test_update_user(self):
# Simulamos una actualización del usuario (ejemplo ficticio)
response = self.client.post(reverse("users:create", kwargs={"name": "Bob"}))
# Verificamos que el cambio se refleje en la base
updated_user = Users.objects.get(pk=self.user.id)
self.assertEqual(updated_user.name, "Bob")
Cada test corre en su propia transacción. Así, si modificas algo, Django lo "deshace" al final, y el siguiente test empieza limpio.
Cargar muchos datos con fixtures
Cuando necesitas muchos datos para la prueba, lo mejor es usar una fixture. Es un archivo con datos de prueba, usualmente en formato JSON.
Cómo crear una fixture
Primero, crea registros reales en tu base de datos. Luego corre:
uv run manage.py dumpdata > users.json
Guarda ese archivo en un directorio llamado fixtures dentro de la app. Ejemplo de contenido:
[
{
"model": "users.user",
"pk": 1,
"fields": {
"password": "superpass",
"email": "johndoe@mail.com",
"name": "John"
}
},
{
"model": "users.user",
"pk": 2,
"fields": {
"password": "password123",
"name": "Alice",
"email": "alicesmith@email.com"
}
}
]
Usar la fixture en un test
from django.test import TestCase
from django.urls import reverse
from .models import Users
class UsersTest(TestCase):
fixtures = ['users.json'] # Django la carga automáticamente antes de cada test
def test_update_user(self):
user = Users.objects.get(pk=1)
# Simular actualización
response = self.client.post(reverse("users:create", kwargs={"name": "Bob"}))
updated_user = Users.objects.get(pk=1)
self.assertEqual(updated_user.name, "Bob")
Así Django ya tiene disponibles los datos antes de correr setUp().
Fíjate que en ningún momento dependimos del código interno de la app. Solo probamos si los resultados son correctos. Esa es la ventaja de las pruebas de integración: si el API de la app devuelve lo esperado, todo va bien, incluso si internamente cambias detalles del código.
Resumen
- Las pruebas de integración simulan el comportamiento real del usuario consultando rutas del proyecto.
- Usamos el
clientde Django para hacer solicitudes simuladas como GET y POST sin activar un servidor real. assertEqual()yassertIn()permiten verificar que las respuestas sean correctas.setUp()prepara datos antes de cada test y garantiza que cada prueba sea independiente.- Las fixtures permiten cargar varios datos desde archivos JSON antes de cada test.
Para acceder completo a curso necesitas un plan básico
El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.