问题
I want to print subprocess output in py.test teardown if the test is failed - or send it to any other human readable output. Is it possible to check if the test has failed in teardown? Any other ways to get the output of subprocess commands only during test failures?
My code:
"""Test different scaffold operations."""
import subprocess
import pytest
from tempfile import mkdtemp
@pytest.fixture(scope='module')
def app_scaffold(request) -> str:
"""py.test fixture to create app scaffold."""
folder = mkdtemp(prefix="websauna_test_")
cmdline = ["..."]
worker = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
worker.wait(timeout=5.0)
if worker.returncode is not None:
raise AssertionError("scaffold command did not properly exit: {}".format(" ".join(cmdline)))
def teardown():
worker.terminate()
# XXX: Hard to capture this only on failure for now
print(worker.stdout.read().decode("utf-8"))
print(worker.stderr.read().decode("utf-8"))
request.addfinalizer(teardown)
回答1:
You can decorate the test with a function that catches exceptions in the test. If there is an exception, log the process output:
import functools
import subprocess
import pytest
def catch_exception(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
worker = kwargs['app_scaffold']
try:
return func(*args, **kwargs)
except Exception as e:
print('stdout:', worker.stdout.read().decode("utf-8"))
print('stderr:', worker.stderr.read().decode("utf-8"))
raise
return wrapper
@pytest.fixture(scope='module')
def app_scaffold(request) -> subprocess.Popen:
"""py.test fixture to create app scaffold."""
cmdline = ["echo", "something"]
worker = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
worker.wait(timeout=5.0)
return worker
@catch_exception
def test_foo(app_scaffold):
assert False
This code leaves out some details from your example, but I think it should contain all you need to handle your case.
回答2:
You can actually capture the stdout/stderr created during execution with the capsys
and capfd
fixtures: (https://pytest.org/latest/capture.html)
回答3:
pytest-instafail plugin might be useful
You can use --instafail option while running tests. To show failure immediately for failed test while execution of other test continue
Refer:https://pypi.python.org/pypi/pytest-instafail
来源:https://stackoverflow.com/questions/34215850/py-test-teardown-see-if-the-test-failed-and-print-subprocess-output