Py.test: Как параметризовать, когда некоторые значения должны возвращать ошибку - PullRequest
1 голос
/ 03 июля 2019

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

Допустим, у меня есть простая функция divide_hundred_by(x), определенная следующим образом:

def divide_hundred_by(x):
    if x == 0: 
         raise ZeroDivisionError('You cannot divide by zero') 
    return 100/x

Теперь я хотел бы протестировать эту функцию на пару значений для x и параметризовать этот тест.Я обнаружил, что могу использовать:

import pytest

@pytest.mark.parametrize('value, expected',
                         [
                             (10, 10),
                             (-2, -50),
                             (0.5, 200)
                         ]
                         )
def test_divide_hundred_by(value, expected):

    with pytest.raises(ZeroDivisionError): 
        divide_hundred_by(0)

    assert divide_hundred_by(value) == expected

Но это гарантирует, что в случае сбоя в части предупреждения весь тест завершится неудачно для всех значений, а это не то, что я хотел бы.

Мне интересно, можно ли написать что-то в форме:

@pytest.mark.parametrize('value, expected',
                         [
                             (10, 10),
                             (-2, -50),
                             (0.5, 200),
                             (0, "ZeroDivisionError") 
                         ]
                         )
def test_divide_hundred_by(value, expected):
    assert divide_hundred_by(value) == expected

, чтобы проверка прошла для других параметров.Я не могу найти что-либо в Интернете по этому вопросу.

1 Ответ

1 голос
/ 03 июля 2019

Как насчет этого - вы можете проверить тип expected, и если он пахнет как класс исключений, используйте вместо него pytest.raises():

import pytest


def divide_hundred_by(x):
    if x == 0:
        raise ZeroDivisionError("You cannot divide by zero")
    return 100 / x


@pytest.mark.parametrize(
    "value, expected",
    [
        (10, 10),
        (-2, -50),
        (0.5, 200),
        (0, ZeroDivisionError),
    ],
)
def test_divide_hundred_by(value, expected):
    if type(expected) == type and issubclass(expected, Exception):
        with pytest.raises(expected):
            divide_hundred_by(value)
    else:
        assert divide_hundred_by(value) == expected

Если у вас есть больше подобных вещей,Вы можете преобразовать бит if/with/else в вспомогательную функцию:

import pytest


def divide_hundred_by(x):
    if x == 0:
        raise ZeroDivisionError("You cannot divide by zero")
    return 100 / x


def check(fn, expected, args=(), kwargs={}):
    if type(expected) == type and issubclass(expected, Exception):
        with pytest.raises(expected):
            fn(*args, **kwargs)
    else:
        assert fn(*args, **kwargs) == expected


@pytest.mark.parametrize(
    "value, expected",
    [(10, 10), (-2, -50), (0.5, 200), (0, ZeroDivisionError)],
)
def test_divide_hundred_by(value, expected):
    check(divide_hundred_by, expected, (value,))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...