Как проверить значение False, возвращаемое функцией, используя pytest - PullRequest
0 голосов
/ 23 октября 2018

У меня есть следующий код функции Python:

class ValidateHotelStars(AbsValidator):
    @staticmethod
    def validate(stars):
        try:
            star = int(stars)
            if star < 0 or star > 5:
                return False
            else:
                return True
        except ValueError:
            return False

Теперь я пытаюсь написать модульный тест для этой функции, используя pytest:

def test_star_value_less_than_zero():
    invalid_stars = [-5, 4, "Five"]
    assert not all(list(map(ValidateHotelStars.validate, invalid_stars)))

Теперь это проходит с нижеприведеннымвывод:

(venv) C:\Users\SUSUBHAT.ORADEV\PycharmProjects\hoteldatareader>python -m pytest
============================= test session starts =============================
platform win32 -- Python 3.6.5, pytest-3.9.1, py-1.7.0, pluggy-0.8.0
rootdir: C:\Users\SUSUBHAT.ORADEV\PycharmProjects\hoteldatareader, inifile:
collected 1 item

hoteldatareader\tests\test_validators.py .                               [100%]

========================== 1 passed in 0.31 seconds ===========================

В идеале это должно произойти сбой, так как когда я запускаю это из Python REPL:

>>> from hoteldatareader.fieldvalidators.validate_hotel_stars import ValidateHotelStars
>>> invalid_stars = [-5, 4, "Five"]
>>> list(map(ValidateHotelStars.validate, invalid_stars))
[False, True, False]

Так что не все из них являются ложными.

Iдумаю, что синтаксис моего теста неправильный.

Может кто-нибудь, пожалуйста, исправьте меня здесь.

Большое спасибо

Ответы [ 4 ]

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

Хотя ответы и дают представление о том, как тестировать список логических значений, содержащих только значения True, все они упускают важные вещи:

По сути, вы выполняете три теста в одном.У этого подхода много недостатков - что если ValidateHotelStars.validate вызывает необработанное исключение в середине списка звезд?Тест не пройден, а оставшиеся звезды не будут проверены.Предполагая, что assert not any(...) терпит неудачу - вы можете сказать, какой из звездных аргументов был причиной неудачи?Все, что вы получаете - это AssertionError: False is not true, без какого-либо понимания точного источника ошибки.

Поскольку вы уже используете pytest, почему бы не использовать одну из его сильных функций?Параметризация теста:

import pytest

@pytest.mark.parametrize('invalid_star', [-5, 4, "Five"])
def test_invalid_star_is_not_validated(invalid_star):
    assert not ValidateHotelStars.validate(invalid_star)

Выполнение теста даст:

$ pytest -v
================================== test session starts ===================================
platform darwin -- Python 3.6.6, pytest-3.9.1, py-1.5.4, pluggy-0.7.1
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow, inifile:
collected 3 items

test_spam.py::test_invalid_star_is_not_validated[-5] PASSED                        [ 33%]
test_spam.py::test_invalid_star_is_not_validated[4] FAILED                         [ 66%]
test_spam.py::test_invalid_star_is_not_validated[Five] PASSED                      [100%]

======================================== FAILURES ========================================
_________________________ test_invalid_star_is_not_validated[4] __________________________

invalid_star = 4

    @pytest.mark.parametrize('invalid_star', [-5, 4, "Five"])
    def test_invalid_star_is_not_validated(invalid_star):
>       assert not ValidateHotelStars.validate(invalid_star)
E       assert not True
E        +  where True = <function ValidateHotelStars.validate at 0x1057936a8>(4)
E        +    where <function ValidateHotelStars.validate at 0x1057936a8> = ValidateHotelStars.validate

test_spam.py:19: AssertionError
=========================== 1 failed, 2 passed in 0.12 seconds ===========================

Мне пришлось написать только один тест, но из-за параметризации pytest запустит его три раза,каждый раз с другим аргументом invalid_star.Теперь, даже если 4 не прошел тест, он все равно продолжит выполнение с "Five".После завершения теста вы сразу увидите, какие именно аргументы не пройдены, какие тесты.Вы не сможете достичь такого уровня детализации, зациклив список аргументов в одном тесте.

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

Используйте следующую проверку

   list1 = [False, True, False] 
   bool(False in list1)
0 голосов
/ 24 октября 2018

Вам не нужно not в утверждении:

def test_star_value_less_than_zero():
invalid_stars = [-5, 4, "Five"]
assert all(list(map(ValidateHotelStars.validate, invalid_stars)))

all() выполняет операцию И для всех элементов, в то время как any() выполняет операцию ИЛИ.Подробнее: https://stackoverflow.com/a/19389957/

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

Если вы хотите проверить все Ложные, вам нужно:

not any(...)

Код теста:

assert not any([False, True, False])

Результаты:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...