Al crear una aplicación Django, se genera automáticamente un tests.py.
La mayoría de los desarrolladores han pensado al menos una vez:
“¿Este archivo... se puede borrar?”
“¿Cómo se supone que debo usarlo?”
De hecho, tests.py es el punto de entrada para pruebas recomendado oficialmente por Django, y
una vez que te acostumbras un poco, se convierte en una gran aseguradora durante refactorizaciones, adiciones de funciones y actualizaciones de versión. (Proyecto Django)
En este artículo:
-
qué es el archivo
tests.py -
cómo escribirlo y ejecutarlo
-
en qué situaciones es especialmente útil
-
ejemplos de uso en la práctica
lo organizamos todo de una vez.
1. ¿Qué es el archivo tests.py?
Django utiliza un framework de pruebas basado en unittest de la biblioteca estándar de Python.
-
Creando una clase de prueba que hereda de
django.test.TestCasey -
escribiendo métodos que comienzan con
test_dentro de ella, -
se ejecutan automáticamente con el comando
./manage.py test.
Cuando creas una aplicación con startapp, se genera un tests.py de forma predeterminada:
-
En proyectos pequeños → un solo
tests.pyes suficiente -
Si el proyecto crece → se recomienda gestionarlo dividiéndolo en un paquete
tests/(test_models.py,test_views.py, etc.) en la documentación de Django.
En otras palabras, se puede entender como “la ubicación básica para pruebas a nivel de aplicación”.
2. ¿Cuándo es útil? (¿Por qué deberíamos usar pruebas?)
Las pruebas en Django brillan especialmente en las siguientes situaciones.
-
Validación de modelos/lógica de negocio
-
Cuanto más compleja sea la lógica de cálculo, los cambios de estado o los métodos personalizados,
-
si creas una prueba, puedes realizar refactorizaciones con confianza en futuras modificaciones.
-
-
Comprobación de vistas/URLs/permisos
-
Verificar si el código de respuesta varía según la autenticación
-
Comprobar si maneja adecuadamente redirecciones/errores por entradas incorrectas
-
Asegurarse de que el contexto necesario se pase correctamente a las plantillas
-
-
Prevención de regresiones
- Si solucionaste un error, lo fijas con una prueba para que el mismo problema no vuelva a surgir.
-
Asegurar estabilidad durante actualizaciones de versiones
-
Cuando actualizas Django o bibliotecas,
-
puedes ejecutar
./manage.py testantes de continuar.
-
3. Ejemplo más básico de tests.py
3-1. Prueba de modelo
# myapp/tests.py
from django.test import TestCase
from .models import Article
class ArticleModelTests(TestCase):
def setUp(self):
self.article = Article.objects.create(
title="Título de prueba",
content="Contenido",
views=0,
)
def test_increase_views(self):
# dado
self.assertEqual(self.article.views, 0)
# cuando
self.article.increase_views()
# entonces
self.assertEqual(self.article.views, 1)
-
TestCasees una clase de Django que extiendeunittest.TestCase. -
Cada prueba se ejecuta de forma aislada en unidades de transacción, y la base de datos se revierte entre pruebas para evitar interferencias.
4. Cómo probar vistas/URLs – Usando Client
Django proporciona un cliente HTTP de pruebas django.test.Client.
Puedes enviar solicitudes GET/POST a URLs y comprobar las respuestas sin levantar un servidor real.
4-1. Prueba de vista simple
# myapp/tests.py
from django.test import TestCase
from django.urls import reverse
from .models import Article
class ArticleViewTests(TestCase):
def setUp(self):
self.article = Article.objects.create(
title="Artículo 1",
content="Contenido",
views=0,
)
def test_article_detail_page_returns_200(self):
url = reverse("article_detail", args=[self.article.id])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Artículo 1")
Los puntos clave son:
-
self.client: la instancia del cliente de prueba que se proporciona por defecto enTestCase -
reverse("article_detail", args=[...]): en lugar de codificar la URL, busca por el nombre de la URL. -
assertContains: comprueba si una cadena específica está incluida en el cuerpo de la respuesta.
4-2. Pruebas de verificación de inicio de sesión/permisos
from django.contrib.auth import get_user_model
class ArticlePermissionTests(TestCase):
def setUp(self):
self.user = get_user_model().objects.create_user(
username="tester",
password="pass1234",
)
self.article = Article.objects.create(
title="secreto",
content="Mensaje secreto",
views=0,
)
def test_anonymous_user_redirected_to_login(self):
url = reverse("article_edit", args=[self.article.id])
response = self.client.get(url)
self.assertEqual(response.status_code, 302)
self.assertIn("/accounts/login", response["Location"])
def test_logged_in_user_can_access_edit_page(self):
self.client.login(username="tester", password="pass1234")
url = reverse("article_edit", args=[self.article.id])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
-
verificamos si se redirige a los usuarios anónimos
-
si los usuarios que han iniciado sesión pueden acceder correctamente
Se pueden identificar errores relacionados con permisos desde el principio.
5. ¿Cuándo/ cómo ejecutar tests.py?
5-1. Ejecutar todas las pruebas
$ python manage.py test
- Busca y ejecuta automáticamente desde archivos
test*.pyen el directorio actual
subclases deunittest.TestCaseodjango.test.TestCase.
5-2. Ejecutar solo una aplicación específica
$ python manage.py test myapp
5-3. Ejecutar solo un módulo/clase/método específico
# todo el módulo myapp.tests
$ python manage.py test myapp.tests
# caso de prueba específico
$ python manage.py test myapp.tests.ArticleViewTests
# método de prueba específico
$ python manage.py test myapp.tests.ArticleViewTests.test_article_detail_page_returns_200
Es bueno tener el hábito de ejecutar rápidamente solo las partes modificadas durante el desarrollo.
6. Ampliando tests.py a un paquete de pruebas
A medida que el proyecto crece, tests.py solo no es suficiente.
La documentación de Django también recomienda dividirlo en una estructura de paquetes. (Proyecto Django)
Ejemplo:
myapp/
tests/
__init__.py
test_models.py
test_views.py
test_forms.py
test_api.py
Dentro de cada archivo:
# myapp/tests/test_models.py
from django.test import TestCase
from myapp.models import Article
class ArticleModelTests(TestCase):
...
Se puede dividir así y la ejecución sigue siendo la misma.
$ python manage.py test myapp # todo
$ python manage.py test myapp.tests.test_models # solo pruebas de modelo
7. Algunos casos de uso en la práctica
7-1. Usar pruebas para “reproducir errores” y evitar regresiones
-
Error en producción
-
Escribir una prueba para reproducir en local (debe fallar para ser correcto)
-
Modificar el código
-
Confirmar que la prueba tiene éxito
-
Agregar a
gitla prueba y el código modificado juntos
De esta manera, puedes asegurarte de que no aparezcan los mismos errores en futuras refactorizaciones.
7-2. Fijar el formato de respuesta de la API
Al colaborar con el frontend, el formato de respuesta de la API es muy importante.
class ArticleApiTests(TestCase):
def setUp(self):
self.article = Article.objects.create(
title="Título de API",
content="Contenido",
views=0,
)
def test_article_detail_api_response(self):
url = reverse("api:article-detail", args=[self.article.id])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
data = response.json()
self.assertEqual(data["id"], self.article.id)
self.assertIn("title", data)
self.assertIn("content", data)
-
Especificar qué campos deben incluirse en la respuesta.
-
Si se cambian o eliminan accidentalmente los nombres de los campos, el test fallará inmediatamente.
7-3. Pruebas de la lógica de validación de formularios
from .forms import ArticleForm
class ArticleFormTests(TestCase):
def test_title_is_required(self):
form = ArticleForm(data={"title": "", "content": "Contenido"})
self.assertFalse(form.is_valid())
self.assertIn("title", form.errors)
def test_valid_form(self):
form = ArticleForm(data={"title": "Título", "content": "Contenido"})
self.assertTrue(form.is_valid())
- Puedes dejar las reglas de validación del formulario documentadas como pruebas.

8. Conclusión – No borres tests.py y prueba a usarlo correctamente una vez
En resumen:
El
tests.pyes el archivo que crea “la red de seguridad de la aplicación Django”.
-
Al principio es tedioso, pero,
-
una vez que experimentas el flujo de desarrollo basado en pruebas,
-
el estrés durante refactorizaciones, adiciones de funciones y actualizaciones de versión se reduce considerablemente.
En un proyecto real:
-
Cuando crees nuevas funcionalidades – agrega al menos 1 o 2 pruebas al mismo tiempo.
-
Cuando corrijas errores – asegúrate de primero escribir la prueba que reproduce ese error.
-
Cuando comiences a hacer crecer el proyecto – refactoriza
tests.pya un paquetetests/.
Si sigues este patrón, experimentarás un desarrollo completamente diferente al de un “proyecto Django sin pruebas”.
No hay comentarios.