我有以下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]
所以并非所有人都是假的。
我认为我的测试语法不正确。
有人可以在这里纠正我。
非常感谢
答案 0 :(得分:1)
如果要检查所有False,则需要:
not any(...)
assert not any([False, True, False])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
答案 1 :(得分:1)
尽管答案确实可以帮助您了解如何测试仅包含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"
。测试运行完成后,您可以立即查看哪些确切的参数未通过哪些测试。通过在单个测试中循环参数列表,您将无法达到这一级别的详细信息。
答案 2 :(得分:-1)
使用以下检查
list1 = [False, True, False]
bool(False in list1)
答案 3 :(得分:-1)
您的断言中不需要not
:
def test_star_value_less_than_zero():
invalid_stars = [-5, 4, "Five"]
assert all(list(map(ValidateHotelStars.validate, invalid_stars)))
all()
对所有元素执行AND操作,而any()
执行OR操作。更多详细信息:https://stackoverflow.com/a/19389957/