Testing y Debugging en
python
Una introducción
“Program testing can be used to show the
presence of bugs, but never to show their
absence!”
― Edsger W. Dijkstra
“El testeo de programas puede ser usado para
mostrar la existencia de errores, pero nunca
su ausencia”
― Edsger W. Dijkstra
Que es un error
Cuando no hace lo que corresponde
Nosotros creemos que el programa hace algo (o queremos que haga algo)
Y el programa hace otra cosa.
Test
Verificar que el programa haga lo que yo digo
Devolver el mínimo y el máximo
El software a testear elemento de una lista.
min_max([1]) -> (1,1)
def min_max(elems):
if not elems:
min_max([2]) -> (2,2)
raise ValueError('Secuencia vacía no tiene mínimo ni min_max([1,1]) -> (1,1)
máximo') min_max([1,30,100]) -> (1,100)
min_ = max_ = elems[0]
for elem in elems:
if elem < min_: pero si ejecutamos
min_ = elem min_max([1,30,100]) -> (1,1)
if max_ > elem:
elem = max
return (min_,max_)
Test con assert
>>> assert True
Una primera forma de testear cosas >>> assert False
es usando la declaración assert. La Traceback (most recent call last):
File "<stdin>", line 1, in ?
idea es que assert chequea que una
AssertionError
condición sea cierta, si es true, sigue >>>
corriendo el programa como si nada
hubiera fallado.
Testeando max_min con assert
def min_max(elems): if __name__ == '__main__':
if not elems: assert min_max([1]) == (1,1)
raise ValueError('Secuencia vacía no tiene assert min_max([2]) == (2,2)
mínimo ni máximo') assert min_max([1,1]) == (1,1)
min_ = max_ = elems[0] assert min_max([1,30,100]) == (1,100)
for elem in elems:
if elem < min_:
min_ = elem
if max_ < elem:
max_ = elem
return (min_,max_)
Antes de ejecutarlo veamos el codigo
Si agregamos la linea def hacer_algo():
if __name__ == "__main__": print "algo"
if __name__ == "__main__":
lo que hacemos es indicar que hacer_algo()
hacer_algo() se ejecute sólo si llamamos
al archivo desde la consola y no si
importamos el archivo desde otro
programa
Ejecutando el código con asserts
De esta forma podemos escribir
todos los test que queremos que
nuestro programa pase antes de
escribir el programa. Esta
perspectiva se llama test driven
development.
Otra función es que podemos
chequear que nada de rompa cuando
hacemos alguna modificación de
nuestro programa.
Testing con Unit Testing
Unit testing
En programación, una prueba unitaria es una La idea es que cada parte del código se pueda
forma de comprobar el correcto funcionamiento testear y no que se testee el programa final. Es
de una unidad de código. Por ejemplo en para poder localizar mejor donde esta el error si
diseño estructurado o en diseño funcional una es que existe.
función o un procedimiento, en
diseño orientado a objetos una clase.
max_min con unittest
import unittest En la misma carpeta creamos el
from maxmin import max_min archivo test_maxmin.py. Allí:
1. Importamos unittest
class TestMinMax(unittest.TestCase): 2. Importamos la función a testear
def test_uno(self): 3. Creamos una clase que hereda
self.assertTrue(min_max([1]) == (1,1)) de unittest.TestCase
def test_dos(self): 4. Añadimos métodos cuyo
self.assertTrue(min_max([1,30,100])==(1,100)) nombre empieza con el string
‘test_’
if __name__ == '__main__':
unittest.main()
Ejecuto: $python -m unittest
maxmin unit test
Vimos que al principio del resultado aparece Otra forma de ejecutarlo como agregamos el main en
una “F” y un “.” esto nos muestra que se el archivo
ejecutaron dos tests, uno exitoso y uno que
falló. $ python test_minmax.py
Más abajo nos muestra información sobre cual Si queremos mas información sobre los test
test falló. debemos escribir
En este caso dice que falló el test_dos: Y que $ python -m unittest -v
falló porque esperaba un true y devuelve un
false
Mas info sobre test y unittest
Existen mas pruebas que se pueden hacer
https://docs.python.org/3/library/unittest.html
https://docs.hektorprofe.net/python/documentacion-y-pruebas/unittest/
Un muy buen video para ver este tema es
https://youtu.be/AgwF37Cdwq8
Houston, tenemos un
problema
Y ahora … ¿Quien podrá ayudarnos?
Aquí hay un bug
Debugging is like being the detective in a crime movie where you are also the
murderer……. and may be the victim also.
Depurar es como ser el detective en una película de crimenes donde también
sos el asesino….. y quizás también la víctima.
Debugging
Una herramienta que ayuda a encontrar errores es llamada depurador.
Usualmente utilizamos el término en inglés: debugger.
Ya encontramos que tenemos un error. Exploremos opciones.
1) Print
2) Thonny
3) Pdb
Debuging con print
La depuración es una actividad parecida a la labor realizada por detectives: se
tienen que estudiar las pistas para inferir los procesos y eventos que han
generado los resultados que se han encontrado.
Normalmente lo primero que hacemos es ir dejando prints en el programa para ir
viendo los valores, ver si entra en una función o no, ver los valores que tiene una
variable en un punto. Todo esto para encontrar pistas que nos digan que es lo
que funciona distinto de lo que esperaba. Pero hay mejores armas.
Debugging con thonny
Debugging con thonny
Si presionamos al lado del botón play, (el bichito verde) se activa el modo
depuración.
Comenzar depuración
Ejecutar la lineq actual del programa
Entrar a la ejecución de la actual del programa
Salir de la ejecución de la función o bloque actual
Seguir ejecutando normalmente
Parar la ejecución
En cada momento el programa indica la linea que se está ejecutando y en el
panel variables muestra los valores de las variables en el scope
Debugging con pydb
Python viene con un debugger incorporado en el módulo pdb, documentado en
https://docs.python.org/3/library/pdb.html
Formas de utilizar pdb
1. Desde el código que queremos inspeccionar
2. Desde la línea de comandos
3. Desde la consola de python
1. Invocando pdb desde el código que falla
1. Invocando pdb desde el código que falla
2. Desde la línea de comandos
3. Desde la consola de python
Cómo utilizar el debugger
La idea es recorrer el código paso a paso, para entender lo que está haciendo.
Podemos:
● imprimir el valor de cualquier expresión
○ p min_
○ p len(elems)
○ p elem > max_
● imprimir el código para ubicarnos
● entrar a una función
● hacer que el código se ejecute normalmente, pero que frene si pasa algo especial
● entrar a una consola interactiva
● Mucho más (ver help)
Tutorial escrito pdb: https://pybonacci.org/2013/06/14/como-depurar-un-programa-python-con-pdb/
Tutorial video pdb: https://www.youtube.com/watch?v=IGkza3_ptr4
Más allá de pdb
ipdb (algunas mejoras visuales y también algunas funciones extra. Fuertemente
vinculado al proyecto IPython)
Algunos editores de código como spyder o pycharm hacen uso de sus interfaces
gráficas para mostrar valores de muchas variables a la vez, poner puntos de
interrupción con el mouse, etc.