【问题标题】:Unit test script returns exit code = 0 even if tests fail即使测试失败,单元测试脚本也会返回退出代码 = 0
【发布时间】:2014-09-18 06:35:08
【问题描述】:

我的测试脚本如下:

import os
import sys
from unittest import defaultTestLoader as loader, TextTestRunner

path_to_my_project = os.path.dirname(os.path.abspath(__file__)) + '/../'
sys.path.insert(0, path_to_my_project)

suite = loader.discover('my_project')
runner = TextTestRunner()
runner.run(suite)

如果我运行这个脚本,输出是:

$ python3 runtest.py
.....F.....
======================================================================
FAIL: test_insert (fate.test.test_operators.OperatorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/chiel/Projects/tfate/libs/fate/../fate/test/test_operators.py", line 16, in test_insert
    self.assertEqual(expected, self.session.text[:14])
AssertionError: 'Foo import sys$' != 'Foo import sys'
- Foo import sys$
?               -
+ Foo import sys


----------------------------------------------------------------------
Ran 12 tests in 0.030s

FAILED (failures=1)

退出代码为零:

$ echo $?
0

但是,Python documentation 声明“默认情况下 main 调用 sys.exit() 并带有指示测试运行成功或失败的退出代码。”

我的脚本有什么问题?

【问题讨论】:

    标签: python unit-testing python-3.x exit-code


    【解决方案1】:

    代码没有使用unittest.main。您需要使用TestResult.wasSuccessful检查结果并手动调用sys.exit

    import sys
    
    ....
    
    ret = not runner.run(suite).wasSuccessful()
    sys.exit(ret)
    

    【讨论】:

    • 我是否正确地说,当用户选择运行测试时 1) 实例化测试类并从中调用测试方法;或 2) 使用 unittest.main() - 代码会自动使用适当的代码处理对 sys.exit 的调用。鉴于,如果用户要使用套件和 TextTestRunner 运行测试,那么他必须明确设置 sys.exit 代码
    • @variable,unittest.main 调用 sys.exit。 1) -> 不调用 sys.exit,如果要退出程序,调用 sys.exit() 2) -> 确实调用 sys.exit,不需要自己调用 sys.exit()。
    【解决方案2】:

    我在获取 TextTestRunner 结果时遇到了一些麻烦。对于像我这样的人,它是这样工作的:

    """Run all tests inside of *_test.py modules located in the same directory."""
    
    
    import sys
    import unittest
    
    
    if __name__ == '__main__':
        test_suite = unittest.defaultTestLoader.discover('.', '*_test.py')
        test_runner = unittest.TextTestRunner(resultclass=unittest.TextTestResult)
        result = test_runner.run(test_suite)
        sys.exit(not result.wasSuccessful())
    

    【讨论】:

    • +1 用于仅 Python 的实现,这在测试发现Unittest Test Discovery987654321@ 的 python 文档中明显缺失
    最近更新 更多