2012-09-25 9 views
8

Ich möchte eine benutzerdefinierte Asser-Methode zu einer TestCase Unterklasse hinzufügen. Ich habe versucht, meine Implementierung aus dem unittest Modul zu kopieren, so dass es das Verhalten des regulären TestCase so genau wie möglich entsprechen würde. (Ich würde es vorziehen, nur an self.assertEqual() zu delegieren, aber das verursacht noch mehr Backtrace-Rauschen, siehe unten.) Das Modul unittest scheint automatisch einige interne Details seiner Implementierung auszublenden, wenn fehlgeschlagene Assertions gemeldet werden.Wie kann ich meine Stack-Frames in einer TestCase-Unterklasse verbergen?

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() 

Der Ausgang dieses als solches:

[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) 

Hinweis, dass die benutzerdefinierte assert Verfahren eine Stapelüberwachung mit zwei Rahmen bewirkt, eine in der Methode selbst, während das Verfahren eine einzige Lager unittest hat Frame, die entsprechende Zeile im Code des Benutzers. Wie kann ich dieses Bildversteckverhalten auf meine eigene Methode anwenden?

Antwort

14

Diese Frage wurde gelöst by Peter Otten on comp.lang.python.

Verschieben Sie MyTestCase in ein separates Modul und definieren Sie eine globale Variable __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

Ich kann nicht glauben, dass diese Frage/Antwort nicht mehr Stimmen erhalten haben! Tolle Information & genau warum ich <3 SO. – dbn

+0

Diese Lösung ist so hilfreich! –

+0

Nicht sicher, ob sich die pipermail auf python.org geändert hat, aber der korrekte Link zu Peters Lösung ist https://mail.python.org/pipermail/python-list/2012-October/632386.html. Sonst vielen Dank für den Zeiger, hat mir wirklich geholfen. –