Python Test Driven Development

Pruebas, pruebas, pruebas!

Es difícil ver cuan importante es probar el software que haces hasta que te llegan te empiezan a reportar fallas en tu código o te ves repitiendo manualmente pruebas de los cambios y funcionalidades que estás desarrollando y más aún la incertidumbre cuando trabajas en un proyecto complejo y no sabes si algo que estás cambiando daña algo más. Finalmente nada como la presión de arreglar algo que está roto en producción.

Es por esto que necesitas hacer pruebas, porque te permite tener mayor confianza que los cambios que haces, desarrollar código; nuevas funcionalidades mucho más rápido. Sí! es verdad cuando haces las pruebas todo el código ahorras tiempo:

  • Tiempo probando que lo que haces cumple con los requerimientos(sobretodo cuando estás haciendo funciones complejas).
  • Tiempo solucionando errores inesperados.
  • Tiempo diseñando! Cuando estás haciendo pruebas identificas muchos más casos de prueba que cuando sólo programas un requerimiento.

¿Como hacer pruebas?

Independientemente del lenguaje de programación que escojas, primero identifica casos que puedes probar según las funcionalidades que te piden, supongamos el siguiente caso:

Caso: Te piden clasificar en unos rangos definidos una entrada de como el siguiente caso:

  • 0 a 5: Rango 1.
  • 6 a 15: Rango 2.
  • 16 a 30: Rango 3.
  • 31 a 90: Rango 4.

Fácil verdad?

Es verdad, es sólo un pequeño requerimiento y seguro vas a encontrar muchos más requerimientos que se entrelazan y que seguro cambian con el tiempo. Seguro se agregan nuevos requerimientos y entonces... ¿Como puedes asegurar que todo sigue funcionando como debería cuando tienes cientos o miles de funciones? ¿Cuando hay cientos de miles de lineas de código? Probar todo manualmente?

mejor... Hagamos algunas pruebas!

Para probar software escrito en python te recomiendo pytest, por su facilidad de uso y configuración. Puedes instalarlo ejecutando así pip install pytest

A continuación te presento una posible solución al requerimiento. Aclaro que no es la única forma de hacerlo y esto es lo que me encanta de programar siempre vas a encontrar una forma de hacer mejor las cosas. Pero por ahora esta será nuestra función.

# utils.py
def get_range(value):  
    if value > 0 and value <= 5:
        return 1
    if value > 5 and value <= 15:
        return 2
    if value > 15 and value <= 30:
        return 3
    if value > 30 and value <= 90:
        return 4

Supongamos que esta función se encuentra en el modulo utils.py entonces hagamos un nuevo modulo llamado test_utils.py y empecemos a probar nuestra función.

La primera prueba podría verse así:

# test_utils.py
from utils import get_range


def test_get_range():  
    value = 0
    assert get_range(value) == 1

Puedes correrla así:

pytest test_utils.py  

Y sí, la prueba falló. Arreglemos la función.

# utils.py
def get_range(value):  
    if value >= 0 and value <= 5:
        return 1
    if value > 5 and value <= 15:
        return 2
    if value > 15 and value <= 30:
        return 3
    if value > 30 and value <= 90:
        return 4
# test_utils.py
from utils import get_range


def test_get_range():  
    assert get_range(0) == 1
    assert get_range(5) == 1
    assert get_range(10) == 2
    assert get_range(15) == 2
    assert get_range(20) == 3
    assert get_range(30) == 3
    assert get_range(45) == 4
    assert get_range(90) == 4

Como puedes ver es sencillo hacer pruebas y en este caso en particular hemos cubierto toda la función y si tenemos que hacer algún cambio como agregar un nuevo rango podemos probar si lo que hagamos genera algún problema en nuestra función.

Y ahora que sigue?

  • Puedes probar si estas comprobando todo el software que estás desarrollando. Esto es muy útil en proyectos grandes ya que te ayuda a tener un mayor grado de confianza cuando hagas cambios. Usaremos pytest-cov puedes instalarlo así: pip install pytest-cov

pytest-cov

Hay muchos más plugins para pytest como por ejemplo para Django entre otros:

  • pytest-django
  • pytest-twisted
  • pytest-cov
  • pytest-xdist
  • pytest-instafail
  • pytest-bdd
  • pytest-konira
  • pytest-timeout
  • pytest-pep8
  • pytest-flakes

Más información de los plugins de pytest aquí

Cuéntame cual ha sido tu experiencia haciendo pruebas en tus proyectos y si te gustaría un nuevo post de pruebas unitarias con pytest en proyectos Django. Escríbeme en twitter.

Carlos Martinez

Read more posts by this author.