Un inevitable compañero a la hora de desarrollar una aplicación
Un código de ejemplo
def hola(nombre):
return 'hola %s' % nombre
>>>print(hola("mundo"))
hola mundo
def hola(nombre):
return 'saludos %s' % nombre
>>>print(hola("mundo"))
saludos mundo
A ver si aún no importa
import os
def ruta_images(img):
return os.path.join('img', img)
>>> print(ruta_images('imagen'))
img/imagen
import os
def ruta_images(img):
return os.path.join('uploads','img', img)
>>> print(ruta_images('imagen'))
uploads/img/imagen
¿Y por que no me procesa la imagen que subí?
Es un set de utilitarios para verificar el comportamiento de una aplicación usando una serie de test cases
Verifica si el resultado que se espera es igual al resultado arrojado por la aplicación
Un test básico
class Original:
def saludo(self, nombre):
return 'saludos %s, soy original' % nombre
import unittest
from mi_paquete.mi_modulo import Original
class OriginalTestCase(unittest.TestCase):
def test_saludo(self):
original = Original()
self.assertEqual('saludos Sergio, soy original',
original.saludo('Sergio'))
$ python -m unittest discover -v
test_saludo (tests.test_mi_modulo.OriginalTestCase) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
import unittest
from mi_paquete.mi_modulo import Original
class OriginalTestCase(unittest.TestCase):
def test_saludo(self):
original = Original()
self.assertEqual('saludos Sergio, no soy original',
original.saludo('Sergio'))
test_saludo (tests.test_mi_modulo.OriginalTestCase) ... FAIL
======================================================================
FAIL: test_saludo (tests.test_mi_modulo.OriginalTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/.../ejemplo/tests/test_mi_modulo.py", line 8, in test_saludo
original.saludo('Sergio'))
AssertionError: 'saludos Sergio, no soy original' != 'saludos Sergio, soy original'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
Es una implementación que simula el comportamiento de un objeto
Es una función o anotación que sirve para reemplazar un objeto por otro simulado
Se hace el reemplazo sobre el módulo que se esta testeando
Uso de patch
import unittest
from mock import patch, Mock
from mi_paquete.otro_modulo import saludo_foraneo
class SaludoOriginalTestCase(unittest.TestCase):
def test_saludo(self):
self.assertEqual('saludos Pythonist, soy original',
saludo_foraneo())
@patch('mi_paquete.otro_modulo.Original.saludo')
def test_mock_saludo(self, mock_saludo):
mock_saludo.return_value = 'cambie la salida'
self.assertEqual('cambie la salida',
saludo_foraneo())
test_saludo (tests.test_mi_modulo.OriginalTestCase) ... ok
test_mock_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
test_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
Nos permite verificar el valor de retorno de las funciones
@patch('mi_paquete.otro_modulo.Original.saludo')
def test_mock_sentinel_saludo(self, mock_saludo):
mock_saludo.return_value = sentinel.salida
self.assertEqual(sentinel.salida,
saludo_foraneo())
Nos permite especificar multiples valores de retorno o bien arrojar excepciones
@patch('mi_paquete.otro_modulo.Original.saludo')
def test_mock_raise_saludo(self, mock_saludo):
mock_saludo.side_effect = ValueError('Lo hice reventar')
self.assertRaises(ValueError)
@patch('mi_paquete.otro_modulo.Original.saludo')
def test_mock_multiple_saludo(self, mock_saludo):
mock_saludo.side_effect = [sentinel.salida1, sentinel.salida2]
self.assertEqual(sentinel.salida1,
saludo_foraneo())
self.assertEqual(sentinel.salida2,
saludo_foraneo())
Al final
test_saludo (tests.test_mi_modulo.OriginalTestCase) ... ok
test_mock_call_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
test_mock_multiple_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
test_mock_raise_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
test_mock_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
test_mock_sentinel_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
test_saludo (tests.test_otro_modulo.SaludoOriginalTestCase) ... ok
----------------------------------------------------------------------
Ran 7 tests in 0.002s
OK