单元测试失败了sys.exit

时间:2014-12-29 13:57:10

标签: python unit-testing python-unittest

我试图用unittest运行我的测试。这是我的结构:

projectname/
    projectname/
        foo.py
        bar.py
    tests/
        test_foo.py
        test_bar.py

我用:

运行它
cd tests/
python -m unittest discover

但在一个文件中,例如 foo.py ,我使用的是sys.exit(0),而unittest并不是真的喜欢它:

$ python -m unittest discover
....E.
======================================================================
ERROR: test_foo (...)
----------------------------------------------------------------------
Traceback (most recent call last):
...
...
File "/home/.../projectname/foo.py", line 12, in write
    sys.exit(0)
SystemExit: 0

----------------------------------------------------------------------
Ran 6 tests in 0.018s

FAILED (errors=1)

sys.exit()使用是自愿的,我无法将其删除。我知道unittest.main函数有一个名为exit的选项:

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

但我想测试 tests 目录中的所有文件。另一种方法是:

if __name__ == '__main__':
    tests = unittest.TestLoader().discover('.')
    unittest.TextTestRunner(verbosity=1).run(tests)

它找到所有 test _ 文件,但sys.exit()使unittest崩溃。

2 个答案:

答案 0 :(得分:4)

sys.exit实际上并没有退出解释器。它只是提出SystemExit。如果该异常使其成为堆栈的顶部,那么解释器将启动退出过程(使用相关的退出值)。

unittest不高兴,因为它正在捕获SystemExit异常(因此解释器实际上不会退出),但测试并未描述为期望引发该异常。

请尝试以下操作。

def test_exit_func(self):
    with self.assertRaises(SystemExit):
        sys.exit(0)

答案 1 :(得分:0)

我不认为在模块中使用sys.exit()是个好主意。但是,如果必须,您应该做的是编写一个测试用例,将模块包装为子进程,可能使用子进程模块,并验证退出代码。您可能还需要一个包装器脚本来调用。换句话说,您调用导入该模块的外部Python脚本,然后退出。然后,unittest框架可以通过检查子进程的返回值来报告通过/失败。