La semana pasada hemos visto los primeros pasos para crear un paquete de Python básico utilizando Cookiecutter e instalarlo en nuestro ordenador. Una de las piezas claves a la hora de garantizar que el código de un proyecto evoluciona sin alterar las funcionalidades existentes son las pruebas unitarias. Con las que podemos evaluar cada una de las funciones y clases implementadas en el paquete de forma automática. Pudiendo comprobar así que una nueva funcionalidad no afecta a las ya existentes. Además de comprobar la compatibilidad con diferentes versiones de Python u otras librerías. Así en esta entrada vamos a ver cómo incluir pruebas unitarias en Python, para lo que usaremos el framework pytest
.
Instalación de pytest
Para facilitar la escritura y ejecución de las pruebas unitarias en Python, como en otros lenguajes, es indispensable contar con un framework que nos ayude en la tarea. En Python uno de lo más utilizados es . El cual vamos a necesitar instalar, para lo que podemos utilizar pip:
pip install pytest
Creación de unas funciones para probar el código
El paquete que hemos creado no tiene hasta ahora ninguna función con una utilizada clara. Por lo que vamos a agregar un nuevo archivo con un par de funciones básicas, la suma y la resta. Es decir, agregaremos el siguiente archivo con el nombre arithmetic.py
con en la carpeta pylane
de nuestro proyecto.
def addition(a, b): return a + b def subtraction(a, b): return a + b
Creación de las pruebas unitarias
Una vez creadas las funciones, crearemos las pruebas (en este ejemplo no estamos usando TDD, donde los pasos serían justamente al revés). Una para comprobar el funcionamiento de la función addition
y otra para subtraction
. Para lo que tendremos que crear un archivo test_arithmetic.py
en la carpeta de pruebas ( test
). El prefijo test_
es lo que indica a pytest
que este archivo contiene pruebas, por lo que es obligatorio. Como cualquier otro archivo lo primero que tenemos que hacer es importar la funciones a probar y posteriormente escribir el código a probar.
from pylane.arithmetic import addition from pylane.arithmetic import subtraction def test_addition(): assert addition(1, 2) == 3 def test_subtraction(): assert subtraction(1, 2) == -1
En este archivo, para cada uno de los métodos a probar definiremos una función que comienza por test_
, concretamente crearemos test_addition
y test_subtraction
. Este prefijo es necesario para que el intérprete sepa que son una prueba. Para evaluar un resultado simplemente tenemos que utilizar la palabra clave assert
antes de una comparación, como se muestra a continuación.
Es decir, realiza una operación con la función a probar y se comprueba si el resultado es el esperado. Para ejecutar las pruebas solamente se tiene que escribir el comando pytest
en la terminal. Observando en este caso que nos indica la existencia de un error en la función test_subtraction
. Si revisamos el código veremos que subtraction
está mal implementada, ya que realiza la suma y no la resta. Si solucionamos el problema veremos que el paquete pasa todas las pruebas escritas.
Pruebas con números reales
Al comparar números reales no es aconsejable utilizar el operador igualdad. El mínimo error numéricos en los cálculos provocará que dos números reales no sean exactamente iguales. Además, cualquier cambio en la configuración puede hacer que la precisión con la que se representa los números reales cambie y en futuro las comparaciones no sean válidas. Lo que debemos hacer es comparar que la diferencia de los dos está por debajo de un umbral de error admitido.
Esta operación se puede hacer manualmente o utiliza la función approx
de pytest
. Una función que nos permite asignar un margen de error tanto de forma absoluta como relativa. Lo único que tenemos que hacer es comparar el resultado con la función approx
en lugar de un valor. Por ejemplo, para evaluar un resultado con un margen de error absoluto de 0,001 se puede usar
from pytest import approx from pylane.arithmetic import subtraction def test_rea(): assert subtraction(1, 1.0001) == approx(0, abs=0.001)
Al ejecutar las pruebas vemos que prueba que tal como está actualmente escrita es válida, pero no si se comprarse a con el valor.
Se puede indicar un margen de error relativo en lugar de absoluto indicando el error mediante el parámetro rel
. Lo que puede ser interesante para cuando el orden de magnitud de los resultados puede es diferente.
Conclusiones
En esta segunda entrada se ha visto los pasos para crear set de pruebas unitarias en Python y garantizar así que nuestra librería funcione pueda evolucionar sin problemas. Estas pruebas se han ejecutado en nuestra configuración con nuestra versión de Python, pero la semana que viene veremos los pasos hacer que se evalúan automáticamente en múltiples versiones de python.
Publicidad