pytest可以在失败时抛出stderr吗?

时间:2017-03-22 10:04:48

标签: python pytest stderr

我正在通过Python脚本运行pytest,我希望它知道pytest是否失败了。对我来说直观的方法是在pytest的出口处捕获任何stderr,但我似乎无法找到一种方法来做到这一点。有什么提示吗?

我的测试看起来像这样:

def test_2():
  object = Object()
  object.func()
  assert object.property == expected_value

测试的调用方式如下:

pytest.main([path_to_test, "-s"])

我想知道即使一个断言是否已经失败,并且做了些什么,也许是这样:

err = io.StringIO()
with contextlib.redirect_stderr(err):
  pytest.main([path_to_test, "-s"])

所以基本上我希望pytest在stderr中抛出任何东西,如果任何测试都失败了。

我发现的一个解决方案是用一个立即抛出错误的函数替换断言,但不是所有的测试都运行了。

编辑: 好的,我刚才有了另一个想法,看起来像这样:

def assert_test(test_case):
  if not test_case:
      sys.stderr.write("failure")
  assert test_case

我想我发现了一些对我有用的东西,但我觉得很奇怪,没有内置或更漂亮的解决方案......

修改编辑: 好的,这样解决方案会破坏日志记录。我已经使用猴子修补断言... IDK,如果这是一个好主意。

class AssertionError():
def __init__(self, *args, **kwargs):
    sys.stderr.write("failure")
    raise builtins.AssertionError

现在调用脚本知道是否有失败。

2 个答案:

答案 0 :(得分:0)

了解测试是否失败的直观且正确的方法是代码中的断言失败。这将由pytest捕获,它将打印此测试的捕获消息。

更进一步,有多种方法可以达到你想要的效果。首先,请注意pytest具有捕获机制,捕获指向stdout或stderr的所有内容。为了禁用机制,您可以使用-s参数提供pytest。然后,您可以通过调用sys.stderr.write(...)将您的消息写入stderr,或者您可以使用或更高级地使用记录器。您还可以提供其他捕获方法,如文件描述符,并检查其内容。但同样,这不应该是探测测试是否通过的方法。

在您上次编辑后,我想我更清楚地了解您要做的事情。对于更漂亮的解决方案,您可以尝试使用pytest.raises,这将在pytest级别引发异常。这将影响pytest程序的返回码。您需要做的是检查返回值是否不同于1以检查是否有错误。

答案 1 :(得分:0)

pytest.main()会返回退出代码,因此如果您在整个运行中查找通过/失败,则可以检查返回值,就像在shell脚本中一样。它非常粗粒度,但它只是整个测试运行的一次通过/失败值。

根据文档the following exit codes are defined

  
      
  • 退出代码0:收集并成功通过所有测试
  •   
  • 退出代码1:收集并运行测试,但部分测试失败
  •   
  • 退出代码2:用户中断测试执行
  •   
  • 退出代码3:执行测试时发生内部错误
  •   
  • 退出代码4:pytest命令行使用错误
  •   
  • 退出代码5:未收集任何测试
  •