TDD ✅ Una introdución al Test Driven development.¶
Introducción¶
El objetivo de este blog es hacerles una introduccion al desarrollo basado en pruebas aplicado a Data Science usando Test Driven Development, esta técnica es muy usada en otras aréas de programacion.
¿Qué es el Test Driven Development?¶
En palabras simples, el desarrollo guiado por pruebas pone las pruebas en el corazón de nuestro trabajo. En su forma más simple consiste en un proceso iterativo de 3 fases:
- Red: Escribe un test que ponga a prueba una nueva funcionalidad y asegurate de que el test falla
- Green: Escribe el código mínimo necesario para pasar ese test
- Refactor: Refactoriza de ser necesario
@pytest.mark.parametrize(
"number, expected",
[
(2, 'par'),
])
def test_paridad(number, expected):
assert paridad(number) == expected
Ahora, se escribe la función paridad
(fase green):
def paridad(n:int)->str:
"""
Determina si un numero natural es par o no.
:param n: numero entero
:return: 'par' si es el numero es par; 'impar' en otro caso
"""
return 'par' if n%2==0 else 'impar'
Hemos cometido un descuido a proposito, no hemos testeado el caso si el número fuese impar, por lo cual reescribimos el test (fase refactor)
@pytest.mark.parametrize(
"number, expected",
[
(2, 'par'),
(3, 'impar'),
])
def test_paridad(number, expected):
assert paridad(number) == expected
¿Porqué debería usarlo?¶
Existen varias razones por las que uno debería usar TDD. Entre ellas podemos encontrar:
- Formular bien nuestros pensamientos mediante la escritura de un test significativo antes de ponernos a solucionar el problema nos ayuda a clarificar los límites del problema y cómo podemos resolverlo. Con el tiempo esto ayuda a obtener un diseño modular y reusable del código.
- Escribir tests ayuda la forma en que escribimos código, haciéndolo más legible a otros. Sin embargo, no es un acto de altruismo, la mayoría de las veces ese otro es tu futuro yo.
- Verifica que el código funciona de la manera que se espera, y lo hace de forma automática.
- Te permite realizar refactoring con la certeza de que no has roto nada.
- Los tests escritos sirven como documentación para otros desarrolladores.
- Es una práctica requerida en metodologías de desarrollo de software agile.
Evidencia empírica¶
El 2008, Nagappan, Maximilien, Bhat y Williams publicaron el paper llamado Realizing Quality Improvement Through Test Driven Development - Results and Experiences of Four Industrial Teams, en donde estudiaron 4 equipos de trabajo (3 de Microsoft y 1 de IBM), con proyectos que variaban entre las 6000 lineas de código hasta las 155k. Estas son parte de sus conclusiones:
Todos los equipos demostraron una baja considerable en la densidad de defectos: 40% para el equipo de IBM, y entre 60-90% para los equipos de Microsoft.
Como todo en la vida, nada es gratis:
⏱️Incremento del tiempo de desarrollo varía entre un 15% a 35%.
Sin embargo...
Desde un punto de vista de eficacia este incremento en tiempo de desarrollo se compensa por los costos de mantención reducidos debido al incremento en calidad.
¿Puedo usar TDD siempre?¶
No, pero puedes usarlo casi siempre. El análisis exploratorio es un caso en que el uso de TDD no hace sentido. Una vez que tenemos definido el problema a solucionar y un mejor entendimiento del problema podemos aterrizar nuestras ideas a la implementación vía testing.
Librerías disponibles¶
Acá listamos algunas librerías de TDD en Python:
- unittest: Módulo dentro de la librería estándar de Python. Permite realizar tests unitarios, de integración y ent-to-end.
- doctest: Permite realizar test de la documentación del código (ejemplos: Numpy o Pandas).
- pytest: Librería de testing ampliamente usada en proyectos nuevos de Python.
- nose: Librería que extiende unittest para hacerlo más simple.
- coverage: Herramienta para medir la cobertura de código de los proyectos.
- 🌟 highly recommended: tox: Herramienta para facilitar el test de una librería en diferentes versiones e intérpretes de Python.
- hypothesis: Librería para escribir tests vía reglas que ayuda a encontrar casos borde.
- Behavior Driven Development, un proceso de desarrollo derivado del TDD.