2009-02-17 4 views
1

Comment puis-je rendre le module unittest de python show output pour chaque assertion, plutôt que d'échouer au premier par cas de test? Il serait beaucoup plus facile de déboguer si je pouvais voir le schéma complet des échecs plutôt que seulement le premier. Dans mon cas, les assertions sont basées sur quelques boucles sur un tableau contenant un objet plus quelques noms de fonctions et la sortie attendue (voir ci-dessous), donc il n'y a pas de moyen évident (du moins pour moi) de juste séparer toutes les affirmations dans une TestCase séparée:Rendre la sortie pyunit show pour chaque assertion

import unittest 
import get_nodes 

class mytest2(unittest.TestCase): 
    def testfoo(self): 
     root = get_nodes.mmnode_plus.factory('mytree.xml') 

     tests = [ 
      (root, {'skip_traversal': False, 'skip_as_child': True, 'skip_as_parent': False, 'is_leaf': False}), 
      (root[0], {'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': False, 'is_leaf': False}), 
      (root[1], {'skip_traversal': True, 'skip_as_child': True, 'skip_as_parent': True}), 
      (root[1][0], {'skip_traversal': True}), 
      (root[0][0], {'is_leaf': False, 'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': False}), 
      (root[0][0][0], {'is_leaf': True, 'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': True}), 
      (root[0][4], {'skip_traversal': True, 'skip_as_child': True, 'skip_as_parent': True}), 
      (root[0][7], {'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': True}), 
     ]  

     for (node, states) in tests: 
      for test_state, exp_result in states.iteritems(): 
       self.assertEqual(node.__getattribute__(test_state)(), exp_result, "unexpected %s for state %s of node %s %s" % (not exp_result, test_state, repr(node), repr(node.__dict__))) 

unittest.main() 

obj.__getattribute__('hello') retours obj.hello donc node.__getattribute__(test_state)() est ma façon d'appeler la fonction membre du noeud dont le nom est stocké dans la variable test_state.

Répondre

1

j'ai pu le faire en faisant de nouvelles classes de TestCase dynamiquement en utilisant le type builtin() usine:

root = get_nodes.mmnode_plus.factory('somenodes.xml') 

tests = [ 
    (root, {'skip_traversal': False, 'skip_as_child': True, 'skip_as_parent': False, 'is_leaf': False}), 
    (root[0], {'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': False, 'is_leaf': False}), 
    (root[1], {'skip_traversal': True, 'skip_as_child': True, 'skip_as_parent': True}), 
    (root[1][0], {'skip_traversal': True}), 
    (root[0][0], {'is_leaf': False, 'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': False}), 
    (root[0][0][0], {'is_leaf': True, 'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': True}), 
    (root[0][4], {'skip_traversal': True, 'skip_as_child': True, 'skip_as_parent': True}), 
    (root[0][7], {'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': True}), 
] 

i = 0 
for (node, states) in tests: 
    for test_state, exp_result in states.iteritems(): 

     input = node.__getattribute__(test_state)() 
     errstr = "expected %s, not %s for state %s of node %s" % (input, exp_result, test_state, repr(node)) 

     locals()['foo' + str(i)] = type('foo' + str(i), (unittest.TestCase,), 
      {'input': input, 'exp_result': exp_result, 'errstr': errstr, 'testme': lambda self: self.assertEqual(self.input, self.exp_result, self.errstr)}) 
     i += 1 
2
import unittest 
import get_nodes 

class TestSuper(unittest.TestCase): 
    def setUp(self): 
     self.root = get_nodes.mmnode_plus.factory('mytree.xml') 
    def condition(self, aNode, skip_traversal, skip_as_child, skip_as_parent, is_leaf): 
     self.assertEquals(skip_traversal, aNode.skip_traversal) 
     self.assertEquals(skip_as_child, aNode. skip_as_child) 
     self.assertEquals(skip_as_parent, aNode. skip_as_parent) 
     self.assertEquals(is_leaf , aNode. is_leaf) 

class TestRoot(TestSuper): 
    def testRoot(self): 
     self.condition(self.root, **{'skip_traversal': False, 'skip_as_child': True, 'skip_as_parent': False, 'is_leaf': False}) 

class TestRoot0(TestSuper): 
    def testRoot0(self): 
     self.condition(self.root[0], **{'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': False, 'is_leaf': False}) 

class TestRoot1(TestSuper): 
    def testRoot1(self): 
     self.condition(self.root[1], **{'skip_traversal': True, 'skip_as_child': True, 'skip_as_parent': True}) 

class TestRoot10(TestSuper): 
    def testRoot10(self): 
     self.condition(self.root[1][0], **{'skip_traversal': True}) 

class TestRoot00(TestSuper): 
    def testRoot00(self): 
     self.condition(self.root[0][0], **{'is_leaf': False, 'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': False}) 

class TestRoot0(TestSuper): 
    def testRoot000(self): 
     self.condition(root[0][0][0], **{'is_leaf': True, 'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': True}) 

class TestRoot04(TestSuper): 
    def testRoot04(self): 
     self.condition(self.root[0][4], **{'skip_traversal': True, 'skip_as_child': True, 'skip_as_parent': True}) 

class TestRoot07(TestSuper): 
    def testRoot07(self): 
     self.condition(self.root[0][7], **{'skip_traversal': False, 'skip_as_child': False, 'skip_as_parent': True}) 

unittest.main() 
+0

ne pouvait pas être quelque chose comme ceci généré dynamiquement à partir du même tableau? –

+0

@ ʞɔıu: Puisque je n'ai aucune patience avec les métaclasses, ma réponse est non. Il est tout à fait possible de créer une métaclasse qui génère toutes ces classes individuelles à partir d'une liste de valeurs. Il est tout à fait possible d'utiliser des templates Jinja pour le générer aussi. Les tests DOIVENT être simples, donc je préfère copier et coller. –

Questions connexes