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

Can pytest throw stderr on failure?

我通过 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

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

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

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

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

pytest.main() return 是退出代码,因此如果您要在整个 运行 上寻找 pass/fail,您可以检查 return 值,就像在 shell 脚本中一样。它的粒度非常粗,但是,它只是整个测试 运行.

的一个 pass/fail 值

根据文档,the following exit codes are defined:

  • Exit code 0: All tests were collected and passed successfully
  • Exit code 1: Tests were collected and run but some of the tests failed
  • Exit code 2: Test execution was interrupted by the user
  • Exit code 3: Internal error happened while executing tests
  • Exit code 4: pytest command line usage error
  • Exit code 5: No tests were collected