Introducción a la Computación Testing en Python Maximiliano Geier Facultad de Ciencias Exactas y Naturales, UBA 17/06/2014 Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 1 / 13
Qué era testing? Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 2 / 13
Qué era testing (funcional)? Técnica dinámica de verificación de software. Busca contrastar la salida del programa con un documento que diga lo que se supone que debe hacer (por ejemplo, la especificación). Permite encontrar errores, pero no demostrar su ausencia. Tres niveles: 1 Test de sistema 2 Test integración 3 Test de unidad Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 3 / 13
Test de unidad Test de caja negra: no sé cómo está implementado el módulo y pruebo con entradas que me parezcan interesantes, casos borde, etc. Test de caja blanca: miro la implementación y pruebo con casos representativos para intentar cubrir todo el dominio. Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 4 / 13
Testing en Python Cómo se escriben casos de test en Python? A mano unittest unittest es un módulo para hacer testing de unidad en Python, siguiendo una filosofía de diseño similar a la que tienen JUnit en Java y Beck s Testing Framework en Smalltalk. Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 5 / 13
Testing usando unittest Receta 1 Elegir una unidad de código para probar 2 Importarla import mi_modulo 3 Importar el módulo unittest import unittest 4 Definir una clase que herede de la clase unittest.testcase class TestsDeMiTAD(unittest.TestCase):... 5 Pensar algún caso de test interesante 6 Definir un método para ese caso de test e implementarlo def test_interesante(self):... 7 Volver a 5 mientras sea necesario 8 Terminar con el siguiente bloque de código: if name == " main ": unittest.main() Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 6 / 13
Ejemplo: clase Inversor Definimos una clase sencilla que devuelve el inverso multiplicativo de un número: class Inversor: def init (self, n): self.v = 1/n def valor(self): return self.v Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 7 / 13
Ejemplo: clase Inversor from inversor import Inversor import math import unittest class TestInversor(unittest.TestCase): def test_unidad(self): """Testea que el inverso de la unidad sea la unidad""" def test_cero(self): """Testea que falle cuando se pide el inverso de cero""" def test_otro(self): """Testea un valor que tiene un inverso distinto de si mismo""" def test_doble_inversion(self): """Testea que invertir el inverso de un numero de el numero original""" if name == " main ": unittest.main() Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 8 / 13
Métodos assert Al heredar de la clase unittest.testcase, tenemos acceso a varios métodos que nos hacen más fácil escribir los casos de test. Método assert self.assertequal(a, b) self.asserttrue(x) self.assertlessequal(a, b) self.assertraises(e, f, arg) self.assertitemsequal(a, b) Falla a menos que... a sea igual a b x sea verdadero a sea menor o igual a b llamar a f(arg) dé una excepción de tipo e a tenga los mismos elementos que b Lista completa: http://docs.python.org/3/library/unittest.html#assert-methods Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 9 / 13
Implementando los casos de test Vamos a escribir algunos de los casos de test para ver cómo funciona esto: def test_unidad(self): """Testea que el inverso de la unidad sea la unidad""" self.assertequal(inversor(1).valor(), 1) def test_cero(self): """Testea que falle cuando se pide el inverso de cero""" # llama a Inversor(0) self.assertraises(zerodivisionerror, Inversor, 0) Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 10 / 13
Testeando los tests Para correr los tests: mgeier@ws1:~$ python3.2 test_de_mi_tad.py También se puede ejecutar la siguiente ĺınea: mgeier@ws1:~$ python3.2 -m unittest discover Esta última ĺınea busca todos los casos de test de unittest definidos en la carpeta de trabajo y los ejecuta. Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 11 / 13
Bonus Algunos otros truquitos que les pueden resultar útiles: Para que Python muestre más mensajes cuando ejecuta los casos de test if name == " main ": unittest.main(verbosity=2) Para correr los casos de test desde el intérprete de Python >>> import unittest >>> unittest.main(module= mi_modulo_con_tests, exit=false) Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 12 / 13
Tarea Ejercicio: Implementar casos de test para el TP1 usando unittest. Ejemplos de cosas que pueden probar: 1 Ambos algoritmos calculan correctamente algún ejemplo hardcodeado (por ejemplo, el del enunciado). 2 Si hay un par de puntos con el mismo valor en ambas coordenadas, la distancia mínima es 0. 3 El algoritmo de ordenamiento implementado funciona correctamente para diferentes tamaños de entrada elegidos de forma aleatoria. 4 Ambos algoritmos devuelven pares que se encuentran a la misma distancia (quizás no el mismo) para distintos tamaños de entrada elegidos de forma aleatoria. 5 (Opcional) Cualquier otro caso de test que se les ocurra. Maximiliano Geier (UBA) Clase 25: Testing en Python 17/06/2014 13 / 13