2012-09-25 9 views
8

Quiero agregar un método de declaración personalizada a una subclase TestCase. Intenté copiar mi implementación desde el módulo unittest para que coincidiera lo más posible con el comportamiento del TestCase normal. (Preferiría simplemente delegar a self.assertEqual(), pero esto causa aún más ruido de backtrace, ver a continuación.) El módulo unittest parece ocultar automáticamente algunos detalles internos de su implementación al informar las afirmaciones fallidas.¿Cómo puedo ocultar mis marcos de pila en una subclase de TestCase?

import unittest 

class MyTestCase(unittest.TestCase): 
    def assertLengthIsOne(self, sequence, msg=None): 
     if len(sequence) != 1: 
      msg = self._formatMessage(msg, "length is not one") 
      raise self.failureException(msg) 

class TestFoo(MyTestCase): 
    seq = (1, 2, 3, 4, 5) 

    def test_stock_unittest_assertion(self): 
     self.assertEqual(len(self.seq), 1) 

    def test_custom_assertion(self): 
     self.assertLengthIsOne(self.seq) 


unittest.main() 

La salida de este es como tal:

[email protected] $ python unittest-demo.py 
FF 
====================================================================== 
FAIL: test_custom_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "unittest-demo.py", line 16, in test_custom_assertion 
    self.assertLengthIsOne(self.seq) 
    File "unittest-demo.py", line 7, in assertLengthIsOne 
    raise self.failureException(msg) 
AssertionError: length is not one 

====================================================================== 
FAIL: test_stock_unittest_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "unittest-demo.py", line 13, in test_stock_unittest_assertion 
    self.assertEqual(len(self.seq), 1) 
AssertionError: 5 != 1 

---------------------------------------------------------------------- 
Ran 2 tests in 0.000s 

FAILED (failures=2) 

Tenga en cuenta que el método afirman costumbre provoca un seguimiento de la pila con dos marcos, uno dentro del método en sí mismo, mientras que el método de la unittest sólo tiene una marco, la línea relevante en el código del usuario. ¿Cómo puedo aplicar este comportamiento de ocultamiento de cuadros a mi propio método?

Respuesta

14

Respondió esta pregunta by Peter Otten on comp.lang.python.

Mueva MyTestCase en un módulo separado y defina una variable global __unittest = True.

$ cat mytestcase.py 
import unittest 

__unittest = True 

class MyTestCase(unittest.TestCase): 
    def assertLengthIsOne(self, sequence, msg=None): 
     if len(sequence) != 1: 
      msg = self._formatMessage(msg, "length is not one") 
      raise self.failureException(msg) 

$ cat mytestcase_demo.py 
import unittest 
from mytestcase import MyTestCase 

class TestFoo(MyTestCase): 
    seq = (1, 2, 3, 4, 5) 

    def test_stock_unittest_assertion(self): 
     self.assertEqual(len(self.seq), 1) 

    def test_custom_assertion(self): 
     self.assertLengthIsOne(self.seq) 

if __name__ == "__main__": 
    unittest.main() 

$ python mytestcase_demo.py 
FF 
====================================================================== 
FAIL: test_custom_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "mytestcase_demo.py", line 11, in test_custom_assertion 
    self.assertLengthIsOne(self.seq) 
AssertionError: length is not one 

====================================================================== 
FAIL: test_stock_unittest_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "mytestcase_demo.py", line 8, in test_stock_unittest_assertion 
    self.assertEqual(len(self.seq), 1) 
AssertionError: 5 != 1 

---------------------------------------------------------------------- 
Ran 2 tests in 0.000s 

FAILED (failures=2) 
$ 
+0

No puedo creer que esta pregunta/respuesta no haya recibido más votos! Gran información y exactamente por qué I <3 SO. – dbn

+0

¡Esta solución es tan útil! –

+0

No estoy seguro de si el pipermail en python.org ha cambiado, pero el enlace correcto a la solución de Peter es https://mail.python.org/pipermail/python-list/2012-October/632386.html. Aparte de eso, muchas gracias por el puntero, realmente me ayudó. –

Cuestiones relacionadas