代码之家  ›  专栏  ›  技术社区  ›  ʞɔıu

使PyUnit显示每个断言的输出

  •  1
  • ʞɔıu  · 技术社区  · 16 年前

    如何使python的unittest模块显示每个断言的输出,而不是在每个测试用例的第一个断言处失败?如果我能看到完整的失败模式而不仅仅是第一个,那么调试就会容易得多。

    在我的例子中,断言是基于一个数组上的一对循环,该数组包含一个对象加上一些函数名和预期的输出(见下文),因此没有一种明显的方法(至少对我而言)将每个断言分离为一个单独的测试用例:

    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') 收益率 obj.hello 所以 node.__getattribute__(test_state)() 是调用名存储在测试状态变量中的节点的成员函数的方法。

    2 回复  |  直到 16 年前
        1
  •  2
  •   S.Lott    16 年前
    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()
    
        2
  •  1
  •   ʞɔıu    16 年前

    我可以通过使用builtin type()工厂动态生成新的testcase类来实现这一点:

    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