PyUnit: 如何在第一次失败后停止测试?
我在我的测试框架中使用了以下代码:
testModules = ["test_foo", "test_bar"]
suite = unittest.TestLoader().loadTestsFromNames(testModules)
runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
results = runner.run(suite)
return results.wasSuccessful()
有没有办法让报告(runner.run
?)在第一次失败后就停止,以避免输出太多信息?
4 个回答
这是一个功能。如果你想改变这个功能,你需要创建一个新的类,继承自 TestCase
和/或 TestSuite
,并在 run()
方法中修改逻辑。
补充说明:
我觉得你需要继承 unittest.TestCase
,并在你的类中重写 run()
方法:
def run(self, result=None):
if result is None: result = self.defaultTestResult()
result.startTest(self)
testMethod = getattr(self, self._testMethodName)
try:
try:
self.setUp()
except KeyboardInterrupt:
raise
except:
result.addError(self, self._exc_info())
return
ok = False
try:
testMethod()
ok = True
except self.failureException:
result.addFailure(self, self._exc_info())
result.stop()
except KeyboardInterrupt:
raise
except:
result.addError(self, self._exc_info())
result.stop()
try:
self.tearDown()
except KeyboardInterrupt:
raise
except:
result.addError(self, self._exc_info())
ok = False
if ok: result.addSuccess(self)
finally:
result.stopTest(self)
(我在默认的 run
定义中添加了两个 result.stop()
调用。)
然后你需要修改所有的测试用例,让它们继承这个新类,而不是 unittest.TestCase
。
警告:我没有测试过这段代码。:)
根据尤金的建议,我想出了以下内容:
class TestCase(unittest.TestCase):
def run(self, result=None):
if result.failures or result.errors:
print "aborted"
else:
super(TestCase, self).run(result)
虽然这个方法效果还不错,但每个测试模块都得自己决定是用这个自定义的类还是默认的类,这点有点麻烦。如果能像py.test
的--exitfirst
那样,有个命令行选项就好了……
在这个问题被提出来的九年后,关于“python单元测试早期失败”的搜索结果中,这个问题仍然是最热门的之一。而当我查看其他搜索结果时发现,这些答案对于最近版本的unittest模块已经不再正确了。
unittest模块的文档中提到,https://docs.python.org/3/library/unittest.html#command-line-options 和 https://docs.python.org/2.7/library/unittest.html#command-line-options 显示可以在unittest.main中添加一个参数,failfast=True,或者使用命令行选项-f或--failfast,这样可以在遇到第一个错误或失败时停止测试。这项功能是在2.7版本中添加的。使用这个选项比之前其他答案中提到的那些解决方法要简单得多。
也就是说,只需将你的
unittest.main()
改成
unittest.main(failfast=True)