Отключить захват предупреждений Pytest в одном тесте - PullRequest
0 голосов
/ 04 июня 2019

Мне обычно нравится хук захвата предупреждений pytest, так как я могу использовать его, чтобы заставить мой набор тестов не вызывать никаких предупреждений.Тем не менее, у меня есть один тест, который требует, чтобы предупреждения печатались на stderr для правильной работы.

Как отключить захват предупреждений только для одного теста?

Например, что-то вроде

def test_warning():
    mystderr = StringIO()
    sys.stderr = mystderr
    warnings.warn('warning')
    assert 'UserWarning: warning' in mystderr.getvalue()

(я знаю, что могу использовать capsys, я просто хочу показать основную идею)

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Благодаря сужению в этом обсуждении, я думаю, что вопрос может быть лучше озаглавлен «В pytest, как собирать предупреждения и выводить их стандартные ошибки в одном тесте?».Учитывая эту предложенную формулировку, я думаю, что ответ «это не может, вам нужен отдельный тест».

Если не было стандартного требования по захвату ошибок, вы должны иметь возможность использовать аннотацию @pytest.mark.filterwarnings дляthis.

@pytest.mark.filterwarnings("ignore")
def test_one():
    assert api_v1() == 1

From: https://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings

@ wim указывает на то, что в комментарии это не будет зафиксировано предупреждение, а ответ, который он излагает, фиксирует и утверждает предупреждения.стандартным способом.

Если бы был вывод stderr, но не были выданы предупреждения Python, capsys был бы техникой, как вы говорите https://docs.pytest.org/en/latest/capture.html

Я не думаю, что имеет смысл делать обав тесте pytest из-за природы реализации pytest.

Как отмечалось ранее, pytest перенаправляет stderr и т. д. на внутренний рекордер.Во-вторых, он определяет свой собственный обработчик предупреждений https://github.com/pytest-dev/pytest/blob/master/src/_pytest/warnings.py#L59

По идее он аналогичен ответу на этот вопрос: https://stackoverflow.com/a/5645133/5729872

Я немного поковырялся с переопределением warnings.showwarning(),который отлично работал с vanilla python, но pytest намеренно повторно инициализирует это.

не будет работать в pytest, только прямой питон ->

def func(x):
    warnings.warn('wwarn')
    print(warnings.showwarning.__doc__)
    # print('ewarn', file=sys.stderr)
    return x + 1

sworig = warnings.showwarning

def showwarning_wrapper(message, category, filename, lineno, file=None, line=None):
    """Local override for showwarning()"""
    print('swwrapper({})'.format(file) )
    sworig(message,category,filename,lineno,file,line)

warnings.showwarning = showwarning_wrapper

<- не будет работать в pytest, только прямой питон </em>

Вы, возможно, могли бы добавить обработчик предупреждений в ваш тестовый пример, который будет выводить вstderr ... но это мало что говорит о тестируемом коде.

Это ваша система в конце дня.Если после рассмотрения высказанного @wim замечания о том, что тестирование stderr как таковое может не принести больших результатов, вы решите, что оно вам по-прежнему необходимо, я предлагаю разделить тестирование объекта предупреждения Python (уровень вызывающей стороны python) и содержимого stderr (вызывая shellслой).Первый тест будет рассматривать только объекты предупреждений Python.Новый второй контрольный пример будет вызывать тестируемую библиотеку в виде сценария через popen() или аналогичный и утверждать полученную стандартную ошибку и вывод.

0 голосов
/ 04 июня 2019

Я призываю вас подумать об этой проблеме по-другому.

Если вы хотите утверждать, что какой-то ваш код вызывает предупреждения, вы должны использовать для этого контекст pytest.warns. Проверьте предупреждающее сообщение с помощью match kwarg, избегайте дополнительных сложностей при попытке перехватить его из stderr.

import re
import warnings

import pytest

def test_warning():
    expected_warning_message = "my warning"
    match = re.escape(expected_warning_message)
    with pytest.warns(UserWarning, match=match):
        warnings.warn("my warning", UserWarning)

Это должно быть пределом вашей ответственности за тестирование. Вы не обязаны проверять, что само предупреждение приводит к выводу некоторого вывода на stderr, так как это поведение исходит из стандартного библиотечного кода и оно должен быть протестирован самим Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...