Introducción
La prueba es fundamental en el proceso de desarrollo de software, ya que garantiza que el código se comporta como se espera y está libre de defectos. En Python, pytest
es un popular marco de pruebas que ofrece varias ventajas sobre el módulo estándar unit test
, que es un marco de pruebas integrado de Python y forma parte de la biblioteca estándar. pytest
incluye una sintaxis más simple, mejores salidas, fixtures potentes y un rico ecosistema de plugins. Este tutorial le guiará a través de la configuración de una aplicación de Flask, la integración de fixtures de pytest
y la escritura de pruebas unitarias utilizando pytest
.
Prerrequisitos
Antes de empezar, necesitará lo siguiente:
-
Un servidor que ejecute Ubuntu y un usuario no root con privilegios de sudo y una cortina activa. Para obtener instrucciones sobre cómo configurar esto, elija su distribución de la lista este listado y siga nuestra guía de configuración inicial del servidor. Asegúrese de trabajar con una versión compatible de Ubuntu.
-
Familiaridad con la línea de comandos de Linux. Puede visitar esta guía sobre el primer curso de la línea de comandos de Linux.
-
Un entendimiento básico de la programación en Python y del marco de pruebas
pytest
en Python. Puede referirse a nuestro tutorial sobre el Marco de Pruebas en Python pytest para obtener más información sobrepytest
. -
Python 3.7 o posterior instalado en su sistema Ubuntu. Para aprender cómo ejecutar un script de Python en Ubuntu, puede referirse a nuestro tutorial sobre Cómo ejecutar un script de Python en Ubuntu.
Por qué pytest
es una Alternativa Mejor que unittest
pytest
ofrece varias ventajas sobre el framework integrado unittest
:
-
Pytest le permite escribir pruebas con menos código debecho, utilizando simples declaraciones assert en lugar de los métodos más verbosos requeridos por
unittest
. -
Proporciona un resultado más detallado y legible, haciendo más fácil identificar dónde y por qué falló una prueba.
-
Las fijaciones de Pytest permiten configuraciones de prueba más flexibles y reutilizables que los métodos
setUp
ytearDown
de unittest. -
Facilita la ejecución de la misma función de prueba con múltiples conjuntos de entrada, lo cual no es tan directo en
unittest
. -
Pytest posee una rica colección de plugins que extienden su funcionalidad, desde herramientas de cobertura de código hasta ejecución de pruebas en paralelo.
-
Automáticamente descubre archivos de prueba y funciones que cumplen con sus convenciones de nomenclatura, economizando tiempo y esfuerzo en la gestión de suites de pruebas.
Dada estas ventajas, pytest
a menudo es la opción preferida para las pruebas de Python moderno. Vamos a configurar una aplicación de Flask y escribir pruebas unitarias usando pytest
.
Paso 1 – Configuración del Entorno
Ubuntu 24.04 trae Python 3 por defecto. Abra el terminal y ejecute el siguiente comando para comprobar la instalación de Python 3:
Si Python 3 ya está instalado en su equipo, el comando anterior devolverá la versión actual de la instalación de Python 3. En caso de que no esté instalado, puede ejecutar el siguiente comando para obtener la instalación de Python 3:
A continuación, necesitará instalar el instalador de paquetes pip
en su sistema:
Una vez que pip
esté instalado, vamos a instalar Flask.
Paso 2 – Crear una Aplicación de Flask
Empecemos por crear una aplicación de Flask simple. Cree un nuevo directorio para su proyecto y navegue hasta él:
Ahora, vamos a crear y activar un entorno virtual para gestionar las dependencias:
Instale Flask usando pip
:
Ahora, vamos a crear una aplicación de Flask simple. Cree un archivo nuevo llamado app.py
y agregue el código siguiente:
Esta aplicación tiene tres rutas:
/
: Devuelve un mensaje simple “Hello, Flask!”./about
: Devuelve un mensaje simple “This is the About page”./multiply/<int:x>/<int:y>
: Multiplica dos enteros y devuelve el resultado.
Para ejecutar la aplicación, ejecute el siguiente comando:
Del resultado de arriba puede notar que el servidor se está ejecutando en http://127.0.0.1
y está escuchando en el puerto 5000
. Abra otra consola de Ubuntu y ejecute los siguientes comandos curl
uno por uno:
- GET:
curl http://127.0.0.1:5000/
- GET:
curl http://127.0.0.1:5000/about
- GET:
curl http://127.0.0.1:5000/multiply/10/20
Vamos a comprender qué hacen estas solicitudes GET:
-
curl http://127.0.0.1:5000/
:
Esta envía una solicitudGET
a la ruta raíz (‘/’) de nuestra aplicación Flask. El servidor responde con un objeto JSON que contiene el mensaje “Hello, Flask!”, demostrando la funcionalidad básica de nuestra ruta principal. -
curl http://127.0.0.1:5000/about
:
Esta envía una solicitud GET a la ruta/about
. El servidor responde con un objeto JSON que contiene el mensaje “This is the About page”. Esto muestra que nuestra ruta está funcionando correctamente. -
curl http://127.0.0.1:5000/multiply/10/20
:
Esta envía una solicitudGET
a la ruta/multiply
con dos parámetros: 10 y 20. El servidor multiplica estos números y responde con un objeto JSON que contiene el resultado (200). Esto demuestra que nuestra ruta de multiplicación puede procesar correctamente los parámetros de URL y realizar cálculos.
Estas solicitudes GET
nos permiten interactuar con las API de los puntos finales de nuestra aplicación Flask, obteniendo información o disparando acciones en el servidor sin modificar ningún dato. Son útiles para recuperar datos, probar la funcionalidad de los puntos finales, y verificar que nuestras rutas responden como se espera.
Veamos cada una de estas solicitudes GET
en acción:
Paso 3 – Instalando pytest
y Escribiendo Tu Primera Prueba
Ahora que tienes una aplicación Flask básica, vamos a instalar pytest
y escribir algunas pruebas unitarias.
Instala pytest
mediante pip
:
Crea un directorio llamado tests para almacenar tus archivos de prueba:
Ahora, vamos a crear un nuevo archivo llamado test_app.py
y agregamos el siguiente código:
Vamos a desglosar las funciones en este archivo de prueba:
-
@pytest.fixture def client()
:
Este es un proveedor de pruebas de pytest que crea un cliente de prueba para nuestra aplicación Flask. Utiliza el métodoapp.test_client()
para crear un cliente que puede enviar solicitudes a nuestra aplicación sin ejecutar el servidor real. La declaraciónyield
permite que el cliente sea utilizado en pruebas y luego cerrado correctamente después de cada prueba. -
def test_home(client)
:
Esta función prueba la ruta de inicio (/
) de nuestra aplicación. Envía una solicitud GET a la ruta utilizando el cliente de prueba, luego afirma que el código de estado de la respuesta es 200 (OK) y que la respuesta JSON coincide con el mensaje esperado. -
def test_about(client)
:
Parecido atest_home
, esta función prueba la ruta de acerca de (/about
). Comprueba un código de estado de 200 y verifica el contenido de la respuesta JSON. -
def test_multiply(client)
:
Esta función prueba la ruta de multiplicar con un input válido (/multiply/3/4
). Comprueba que el código de estado es 200 y que la respuesta JSON contiene el resultado correcto de la multiplicación. -
def test_multiply_invalid_input(client)
:
Esta función prueba la ruta de multiplicación con un input no válido (multiply/three/four
). Comprueba que el código de estado es 404 (No Encontrado), lo cual es el comportamiento esperado cuando la ruta no puede concordar las entradas de cadena con los parámetros enteros requeridos. -
def test_non_existent_route(client)
:
Esta función prueba el comportamiento de la aplicación cuando se accede a una ruta que no existe. Envia una solicitud GET a/non-existent
, que no está definida en nuestra aplicación Flask. La prueba afirma que el código de estado de la respuesta es 404 (No Encontrado), garantizando que nuestra aplicación maneja correctamente las solicitudes a rutas no definidas.
Estas pruebas cubren la funcionalidad básica de nuestra aplicación Flask, garantizando que cada ruta responda correctamente a entradas válidas y que la ruta de multiplicación maneja inputs no válidos de manera apropiada. Mediante el uso de pytest
, podemos ejecutar fácilmente estas pruebas para verificar que nuestra aplicación funciona como se espera.
Paso 4 – Ejecución de las Pruebas
Para ejecutar las pruebas, ejecute el siguiente comando:
Por defecto, el proceso de descubrimiento de pytest
buscará de forma recursiva las carpetas actuales y sus subcarpetas buscando archivos que empiezan con el nombre “test_” o que terminen con “_test”. Las pruebas ubicadas en estos archivos se ejecutarán entonces. Debería ver salida similar a:
Esto indica que todas las pruebas se han superado con éxito.
Paso 5: Usar Fixtures en pytest
Las fuciones fixture son utilizadas para proporcionar datos o recursos a las pruebas. Pueden utilizarse para configurar y desconfigurar entornos de prueba, cargar datos o realizar otras tareas de configuración. En pytest
, las fuciones fixture se definen usando el decorador @pytest.fixture
.
Aquí es cómo mejorar la fixture existente. Actualice la fixture del cliente para utilizar la lógica de configuración y desconfiguración:
Este ajuste agrega declaraciones de impresión para demostrar las fases de configuración y desconfiguración en la salida de pruebas. Estas pueden ser reemplazadas con código de gestión de recursos reales si es necesario.
Vamos a intentar ejecutar las pruebas de nuevo:
La opción -v
aumenta la verbosidad, y la opción -s
permite que las declaraciones de impresión se muestren en la salida de la consola.
Debería ver la siguiente salida:
Paso 6: Agregar un Caso de Prueba de Falla
Vamos a agregar un caso de prueba de falla al archivo de pruebas existente. Modifique el archivo test_app.py
y agregue la función de abajo al final para un caso de prueba de falla con un resultado incorrecto:
Vamos a desglosar la función test_multiply_edge_cases
y explicar qué hace cada parte:
-
Prueba con cero:
Esta prueba verifica si la función de multiplicación maneja correctamente la multiplicación por cero. Esperamos que el resultado sea 0 cuando se multiplica cualquier número por cero. Esto es un caso fronterizo importante que hay que probar porque algunas implementaciones podrían tener problemas con la multiplicación por cero. -
Prueba con números grandes:
Esta prueba verifica si la función de multiplicación puede manejar números grandes sin sobrepasar el límite o tener problemas de precisión. Estamos multiplicando dos valores de un millón, esperando un resultado de un billón. Esta prueba es crucial porque verifica los límites superiores de la capacidad de la función. Tenga en cuenta que esto podría fallar si la implementación del servidor no maneja números grandes correctamente, lo que podría indicar la necesidad de bibliotecas de números grandes o un tipo de dato diferente. -
Prueba intencionalmente fallida:
Esta prueba está deliberadamente configurada para fallar. Comprueba si 2 * 3 es igual a 7, lo cual es incorrecto. Esta prueba tiene como objetivo demostrar cómo se ve una prueba fallida en la salida de pruebas. Esto ayuda en la comprensión de cómo identificar y depurar pruebas fallidas, que es una habilidad fundamental en el desarrollo dirigido por pruebas y en los procesos de depuración.
Al incluir estos casos extremos y un fallo intencional, estás probando no solo la funcionalidad básica de tu ruta de multiplicación, sino también su comportamiento bajo condiciones extremas y sus capacidades de reporte de errores. Esta aproximación a las pruebas ayuda a garantizar la robustez y la confiabilidad de nuestra aplicación.
Vamos a intentar ejecutar las pruebas de nuevo:
Deberías ver la siguiente salida:
La mensaje de fallo de arriba indica que la prueba test_multiply_edge_cases
en el archivo tests/test_app.py
falló. específicamente, la última aserción en esta función de prueba causó el fallo.
Este fallo intencional es útil para demostrar cómo se informan las fallas en las pruebas y qué información se proporciona en el mensaje de fallo. Muestra la línea exacta donde ocurrió el fallo, los valores esperados y los valores reales, y la diferencia entre ambos.
En un escenario real, Ud. corregiría el código para que la prueba pasara o ajustaría la prueba si el resultado esperado era incorrecto. Sin embargo, en este caso, la falla es intencional por propósitos educativos.
Conclusión
En este tutorial, cubrimos cómo configurar pruebas unitarias para una aplicación de Flask utilizando pytest
, integrar fixture de pytest
y demostrar cómo se ve una falla de prueba. Al seguir estos pasos, Ud. puede asegurar que sus aplicaciones de Flask son confiables y mantenibles, minimizando errores y mejorando la calidad del código.
Puede referirse a la documentación oficial de Flask y Pytest para aprender más.
Source:
https://www.digitalocean.com/community/tutorials/unit-test-in-flask