zoukankan      html  css  js  c++  java
  • unittest使用过程中sys.exit(not self.result.wasSuccessful())

    起因:

    在运行下面的unittest过程中出现了个Traceback:

    被测试脚本:

    # splitter.py
    def split(line, types=None, delimiter=None):
        """Splits a line of test and optionally performs type conversion.
        For example:
    
        >>> split('GOOD 100 490.50')
        ['GOOD', '100', '490.50']
        >>> split('GOOD 100 490.50', [str, int, float])
        ['GOOD', 100, 490.50]
        >>>
        By default, splitting is perfomed on whitespace, but a different delimiter
        can be selected with the delimiter keyword argument:
    
        >>> split('GOOD, 100, 490.50', delimiter=',')
        ['GOOOD', '100', '490.50']
        >>>
        """
    
        fields = line.split(delimiter)
        if types:
            fields = [ty(val) for ty, val in zip(types, fields)]
        return fields
    
    if __name__ == '__main__':
        # test myself
        import doctest
        doctest.testmod()
    

     测试脚本:

    # testsplitter.py
    import splitter
    import unittest
    
    # unit test
    class TestSplitFunction(unittest.TestCase):
        def setUp(self):
            pass
        def tearDown(self):
            pass
        def testsimplestring(self):
            r = splitter.split('GOOD 100 490.50')
            self.assertEqual(r, ['GOOD', '100', '490.50'])
        def testypeconvert(self):
            r = splitter.split('GOOD 100 490.50', [str, int, float])
            self.assertAlmostEqual(r, ['GOOD', 100, 490.50])
        def testdelimiter(self):
            r = splitter.split('GOOD,100,490.50', delimiter=',')
            self.assertEqual(r, ['GOOD', '100', '490.50'])
    
    # Run unit test
    if __name__ == '__main__':
        unittest.main()
    

     结果:

    ...
    ----------------------------------------------------------------------
    Ran 3 tests in 0.011s
    
    OK
    Traceback (most recent call last):
      File "C:UsersAdministratorDesktopPython Scripts	estsplitter - 副本.py", line 23, in <module>
        unittest.main()
      File "D:Python33libunittestmain.py", line 125, in __init__
        self.runTests()
      File "D:Python33libunittestmain.py", line 267, in runTests
        sys.exit(not self.result.wasSuccessful())
    SystemExit: False
    >>> ================================ RESTART ================================
    >>> 
    ...
    ----------------------------------------------------------------------
    Ran 3 tests in 0.011s
    
    OK
    Traceback (most recent call last):
      File "C:UsersAdministratorDesktopPython Scripts	estsplitter - 副本.py", line 23, in <module>
        unittest.main()
      File "D:Python33libunittestmain.py", line 125, in __init__
        self.runTests()
      File "D:Python33libunittestmain.py", line 267, in runTests
        sys.exit(not self.result.wasSuccessful())
    SystemExit: False
    

     从结果看,所有测试用例是都通过的,但是出现了Traceback,SystemExit: False.

    分析:

    查找到的链接: http://bugs.python.org/issue2821

    这是一个IDLE问题

    IDLE catches the SystemExit function raised by TestProgram().runTests()
    and prints the traceback. Not a bug in unittest.

    因为unittest.main()函数会调用sys.exit()来结束函数进程。使用的参数就是not self.result.wasSuccessful()

    进一步分析:

    那如果是assert过程中出现fail,会是什么样?

    修改测试脚本:

    # testsplitter.py
    import splitter
    import unittest
    
    # unit test
    class TestSplitFunction(unittest.TestCase):
        def setUp(self):
            pass
        def tearDown(self):
            pass
        def testsimplestring(self):
            r = splitter.split('GOOD 100 490.50')
            self.assertEqual(r, ['GOOD', '100', '490.50'])
        def testypeconvert(self):
            r = splitter.split('GOOD 100 490.50', [str, int, float])
            self.assertAlmostEqual(r, ['GOOD', 10, 490.50])  # Modify this line
        def testdelimiter(self):
            r = splitter.split('GOOD,100,490.50', delimiter=',')
            self.assertEqual(r, ['GOOD', '100', '490.50'])
    
    # Run unit test
    if __name__ == '__main__':
        unittest.main()
    

     运行结果:

    ..E
    ======================================================================
    ERROR: testypeconvert (__main__.TestSplitFunction)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "C:UsersAdministratorDesktopPython Scripts	estsplitter - 副本.py", line 16, in testypeconvert
        self.assertAlmostEqual(r, ['GOOD', 10, 490.50])
      File "D:Python33libunittestcase.py", line 683, in assertAlmostEqual
        if round(abs(second-first), places) == 0:
    TypeError: unsupported operand type(s) for -: 'list' and 'list'
    
    ----------------------------------------------------------------------
    Ran 3 tests in 0.077s
    
    FAILED (errors=1)
    Traceback (most recent call last):
      File "C:UsersAdministratorDesktopPython Scripts	estsplitter - 副本.py", line 23, in <module>
        unittest.main()
      File "D:Python33libunittestmain.py", line 125, in __init__
        self.runTests()
      File "D:Python33libunittestmain.py", line 267, in runTests
        sys.exit(not self.result.wasSuccessful())
    SystemExit: True
    

    分析:

    unittest里面的assert和一般的assert是不一样的,即使fail了,其实还是会继续执行其他的测试用例,不会立即跳出函数。最后跳出函数还是调用sys.exit(),只不过这个时候的参数就是True了。

    类似sys.exit(1) - 表示非正常退出。在unittest里面表示有测试用例失败。

    sys.exist(0) - 正常退出。在unittest里面表示测试用例均通过。

  • 相关阅读:
    HDU 4814 Golden Radio Base 模拟
    Java提高篇(三二)-----List总结
    让你提前认识软件开发(28):数据库存储过程中的重要表信息的保存及相关建议
    BBSXP最新漏洞 简单注入检測 万能password
    CodeForce 356A Knight Tournament(set应用)
    POJ--3268--Silver Cow Party【SPFA+邻接表】
    strip 命令的使用方法
    MySQL创建用户权限结果Trigger失败
    Cocos2d-x3.0下一个 Lua与C++打电话给对方
    sharepoint 2013 userprofile 用户信息
  • 原文地址:https://www.cnblogs.com/herbert/p/3244614.html
Copyright © 2011-2022 走看看