Para asegurarme de que los mensajes de error de mi módulo son informativos, me gustaría ver todos los mensajes de error capturados por assertRaises(). Hoy lo hago para cada assertRaises(), pero como hay muchos en el código de prueba, se vuelve muy tedioso.¿Cómo se muestran los mensajes de error capturados por assertRaises() en unittest en Python2.7?
¿Cómo puedo imprimir los mensajes de error para todas las assertRaises()? Estudié la documentación en http://docs.python.org/library/unittest.html sin encontrar la manera de resolverla. ¿Puedo de alguna manera monopatch el método assertRaises()? Prefiero no cambiar todas las líneas de assertRaises() en el código de prueba, ya que con mayor frecuencia uso el código de prueba de la manera estándar.
supongo que esta pregunta está relacionada con Python unittest: how do I test the argument in an Exceptions?
Así es como lo hago hoy. Por ejemplo:
#!/usr/bin/env python
def fail():
raise ValueError('Misspellled errrorr messageee')
Y el código de prueba:
#!/usr/bin/env python
import unittest
import failure
class TestFailureModule(unittest.TestCase):
def testFail(self):
self.assertRaises(ValueError, failure.fail)
if __name__ == '__main__':
unittest.main()
Para comprobar el mensaje de error, simplemente cambiar el tipo de error en los assertRaises() para, por ejemplo, IOError. Entonces puedo ver el mensaje de error:
E
======================================================================
ERROR: testFail (__main__.TestFailureModule)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_failure.py", line 8, in testFail
self.assertRaises(IOError, failure.fail)
File "/usr/lib/python2.7/unittest/case.py", line 471, in assertRaises
callableObj(*args, **kwargs)
File "/home/jonas/Skrivbord/failure.py", line 4, in fail
raise ValueError('Misspellled errrorr messageee')
ValueError: Misspellled errrorr messageee
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
¿Alguna sugerencia? /Jonas
EDIT:
Con los consejos de Robert Rossney me las arreglé para resolver el problema. No está destinado principalmente a errores ortográficos, sino a garantizar que los mensajes de error sean realmente significativos para el usuario del módulo. La funcionalidad normal de unittest (así es como la uso la mayor parte del tiempo) se logra configurando SHOW_ERROR_MESSAGES = False.
Simplemente reemplazo el método assertRaises(), como se ve a continuación. ¡Funciona como el encanto!
SHOW_ERROR_MESSAGES = True
class NonexistantError(Exception):
pass
class ExtendedTestCase(unittest.TestCase):
def assertRaises(self, excClass, callableObj, *args, **kwargs):
if SHOW_ERROR_MESSAGES:
excClass = NonexistantError
try:
unittest.TestCase.assertRaises(self, excClass, callableObj, *args, **kwargs)
except:
print '\n ' + repr(sys.exc_info()[1])
Una fracción de la salida resultante:
testNotIntegerInput (__main__.TestCheckRegisteraddress) ...
TypeError('The registeraddress must be an integer. Given: 1.0',)
TypeError("The registeraddress must be an integer. Given: '1'",)
TypeError('The registeraddress must be an integer. Given: [1]',)
TypeError('The registeraddress must be an integer. Given: None',)
ok
testCorrectNumberOfBytes (__main__.TestCheckResponseNumberOfBytes) ... ok
testInconsistentLimits (__main__.TestCheckNumerical) ...
ValueError('The maxvalue must not be smaller than minvalue. Given: 45 and 47, respectively.',)
ValueError('The maxvalue must not be smaller than minvalue. Given: 45.0 and 47.0, respectively.',)
ok
testWrongValues (__main__.TestCheckRegisteraddress) ...
ValueError('The registeraddress is too small: -1, but minimum value is 0.',)
ValueError('The registeraddress is too large: 65536, but maximum value is 65535.',)
ok
testTooShortString (__main__.TestCheckResponseWriteData) ...
ValueError("The payload is too short: 2, but minimum value is 4. Given: '\\x00X'",)
ValueError("The payload is too short: 0, but minimum value is 4. Given: ''",)
ValueError("The writedata is too short: 1, but minimum value is 2. Given: 'X'",)
ValueError("The writedata is too short: 0, but minimum value is 2. Given: ''",)
ok
testKnownValues (__main__.TestCreateBitPattern) ... ok
testNotIntegerInput (__main__.TestCheckSlaveaddress) ...
TypeError('The slaveaddress must be an integer. Given: 1.0',)
TypeError("The slaveaddress must be an integer. Given: '1'",)
TypeError('The slaveaddress must be an integer. Given: [1]',)
TypeError('The slaveaddress must be an integer. Given: None',)
ok
Por qué seguir utilizando assertRaises si es necesario comprobar los argumentos? ¿Por qué no simplemente atrapar la excepción y examinarla usando 'try' y' except'? –