py.test teardown see if the test failed and print subprocess output

谁说我不能喝 提交于 2019-12-10 10:54:10

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!