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
我通过 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 脚本中一样。它的粒度非常粗,但是,它只是整个测试 运行.
根据文档,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