pytest.mark.parametrize, кажется, может только xfail ожидаемое исключение - PullRequest
0 голосов
/ 15 октября 2018

При параметризации тестов, которые вызывают ожидаемое исключение, я использовал следующую форму:

import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.parametrize(
    'error',
    [None,
     pytest.mark.raises(SomeException('the message'),
                        exception=SomeException),
     pytest.mark.raises(AnotherException('the message'),
                        exception=AnotherException),
     pytest.mark.raises(Exception('the message'),
                        exception=Exception),
     ])
def test_mark_raises(error):
    if error:
        raise error

Обратите внимание, что я установил пакет pytest-raises.Хорошо, это работает, но я недавно заметил, что это вызывает предупреждение об устаревании:

RemovedInPytest4Warning: Applying marks directly to parameters is deprecated, please use pytest.param(..., marks=...) instead.

Хорошо, все в порядке.Мы обновим список параметров.Но это было проблематично.У pytest.param есть аргумент «marks =», но передача в pytest.mark.raises не работает.Единственный способ, которым я нашел использование обработки исключений в pytest.param (который на самом деле, кажется, работает вообще), заключается в следующем:

import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.parametrize(
    'error',
    [None,
     pytest.param(SomeException('the message'),
                  marks=pytest.mark.xfail(exception=SomeException)),
     pytest.param(AnotherException('the message'),
                  marks=pytest.mark.xfail(exception=AnotherException)),
     pytest.param(Exception('the message'),
                  marks=pytest.mark.xfail(exception=Exception)),
     ])
def test_mark_raises(error):
    if error:
        raise error

Хорошо, так что, похоже, это работает, вроде.Но вместо того, чтобы проходить тесты, это не помогает им.

Мне это не нравится.Если я ожидаю, что тест вызовет конкретное исключение, а оно действительно вызывает исключение, то я считаю, что тест пройден, а не 'xfailed'.

И если я проверяю группу pytestрезультаты (1500+ в некоторых случаях), визуально больше работы для определения того, какие тесты xfailing, потому что они ожидают какого-то условия отказа, а какие xfailing, потому что они еще не реализованы (или по какой-то другой причине, которая указывает на то, что нам нужночто-то исправить).

Мне не нравится получать кучу предупреждений, но я также хочу тесты, которые правильно показывают, что они прошли.Есть ли кто-нибудь, кто знает правильную конструкцию для использования с pytest.param в случае ожидаемого исключительного поведения?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Я не был уверен, отвечать ли на мой вопрос или просто обновить вопрос.Поскольку ответ немного многословен, я решил разместить его здесь.

Pytest-Raises Release 0.10 теперь поддерживает поведение, которое я искал.Теперь вы можете настроить параметры исключения следующим образом:

import pytest

class SomeException(Exception):
    pass

@pytest.mark.parametrize(
    'error',
    [None,
     pytest.param(SomeException('the message'),
                  marks=pytest.mark.raises(exception=SomeException)),
     ])
def test_mark_raises(error):
    if error:
        raise error

Это немного более многословно, чем ранее принятая практика помещения метки непосредственно в список параметризации, но она работает, как и ожидалось, ипредупреждения об устаревании исчезают.

0 голосов
/ 17 октября 2018

Если вы хотите отключить предупреждения в выходных данных, вы можете использовать флаг --disable-warnings.

Вы используете xfail для вызова исключения, когда не ожидаете, что тесты не пройдут.Вы должны использовать pytest.raises для создания исключений - ссылка .Если вы хотите использовать маркеры для создания исключений, вы должны использовать собственные маркеры и написать свой собственный сборщик тестов.Пример файла conftest.py:

import pytest

def pytest_runtest_setup(item):
    envmarker = item.get_marker("passwithex")
    if envmarker is not None:
        pytest.raises(ErrorName)

Тестовый код:

import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.parametrize(
    'error',
    [None,
     pytest.param(SomeException('the message'),
                  marks=pytest.mark.passwithex),
     pytest.param(AnotherException('the message'),
                  marks=pytest.mark.xfail(exception=AnotherException)),
     pytest.param(Exception('the message'),
                  marks=pytest.mark.xfail(exception=Exception)),
     ])
def test_mark_raises(error):
    if error:
        raise error
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...