Как полностью заменить вывод pytest для теста пользовательской строкой? - PullRequest
0 голосов
/ 12 февраля 2019

Сценарий

Я пишу пакет, который требует от меня внешнего вызова pytest из pytest, запущенного через subprocess.Таким образом, очевидно, что вывод, полученный из подпроцесса, является именно той ошибкой, которую я хочу отобразить, поскольку в ней есть все приятное форматирование и информация, которую предоставляет pytest.К сожалению, в настоящее время основной вызов pytest показывает только внутренний код моей обертки, а не симпатичный вывод подпроцесса, который после печати выводится только в захваченном разделе stdout pytest.Я хотел бы отформатировать вывод для сбоев и ошибок, как если бы код вызывался напрямую, и скрыть, что был сделан вызов подпроцесса.Следовательно, я хочу полностью заменить вывод для одной тестовой функции другой строкой.Возможно ли это?

MWE

Давайте рассмотрим MWE простой упакованной функции (не делающей ничего полезного, но самое короткое MWE, о котором я мог подумать):

import functools
import json
from subprocess import Popen, PIPE
import sys


def call_something(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # for the sake of simplicity, a dummy call
        p = Popen([sys.executable, '-c', 'import numby'], stderr=PIPE, stdout=PIPE)
        # let's imagine this is the perfect string output we want
        # to print instead of the actual output generated from...
        error = p.communicate()[1].decode("utf-8")

        if p.returncode != 0:
            # ... this line
            raise AssertionError(f'{error}')

    return wrapper

@call_something
def test_something():
    assert 1 == 2

Как вы можете видеть, у меня есть test_something() функция, которая в подпроцессе завершится ошибкой.

Текущий вывод

Если я запускаю pytest с этим файлом, я получаю:

================================== FAILURES ===================================
_______________________________ test_something ________________________________

func = <function test_something at 0x000001EA414F1400>, args = (), kwargs = {}
p = <subprocess.Popen object at 0x000001EA414A67B8>
error = 'Traceback (most recent call last):\r\n  File "<string>", line 1, in <module>\r\nModuleNotFoundError: No module named \'numby\'\r\n'

    def wrapper(*args, **kwargs):
        # for the sake of simplicity, a dummy call
        p = Popen([sys.executable, '-c', 'import numby'], stderr=PIPE, stdout=PIPE)
        # let's imagine this is the perfect string output we want
        # to print instead of the actual output generated from...
        error = p.communicate()[1].decode("utf-8")

        if p.returncode != 0:
            # ... this line
>               raise AssertionError(f'{error}')
E               AssertionError: Traceback (most recent call last):
E                 File "<string>", line 1, in <module>
E               ModuleNotFoundError: No module named 'numby'

test_me.py:18: AssertionError
========================== 1 failed in 0.18 seconds ===========================

Очевидно, я не хочу показывать детали функции оболочки,Вместо

Желаемый вывод

Я хотел бы показать, что происходит в подпроцессе.Вот так и должно выглядеть (или похоже).

================================== FAILURES ===================================
_______________________________ test_something ________________________________

<string captured from subprocess>
========================== 1 failed in 0.11 seconds ===========================

Так что мой вопрос в меньших битах:

Короче вопрос

  • Как заменить pytestвывод для теста с пользовательской строкой из моей оболочки?
...