Reputation: 5723
I have the below Python function code :
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
Now i am trying to write a unit test for this function using pytest :
def test_star_value_less_than_zero():
invalid_stars = [-5, 4, "Five"]
assert not all(list(map(ValidateHotelStars.validate, invalid_stars)))
Now this passes with the below output :
(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 ===========================
This should ideally fail right since when i run this from the Python REPL:
>>> from hoteldatareader.fieldvalidators.validate_hotel_stars import ValidateHotelStars
>>> invalid_stars = [-5, 4, "Five"]
>>> list(map(ValidateHotelStars.validate, invalid_stars))
[False, True, False]
So not all of them are False .
I think the syntax of my test is not correct.
Can someone please correct me here .
Many thanks
Upvotes: 3
Views: 8703
Reputation: 66461
While the answers do give an insight about how to test a list of booleans containing only True
values, they all miss the essential stuff:
Basically, you are doing three tests in one. This approach has many disadvantages - what if ValidateHotelStars.validate
raises an unhandled exception in the middle of the stars list? The test will fail and the remaining stars won't be checked. Assuming assert not any(...)
fails - can you say which of the star arguments was the failure reason? All you get is an AssertionError: False is not true
, without giving you any insight into the exact the error source.
Since you already use pytest
, why not use one its strong features? Parametrize the test:
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)
Running the test will yield:
$ 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 ===========================
I had to write only one test, but due to parametrization, pytest
will run it three times, each time with a different invalid_star
argument. Now, even though 4
fails the test, it will still continue execution with "Five"
. After the test run finishes, you can immediately see what exact arguments fail what tests. You won't be able to achieve this level of details by looping the list of arguments in a single test.
Upvotes: 3
Reputation: 403
Use the following check
list1 = [False, True, False]
bool(False in list1)
Upvotes: -1
Reputation: 49812
If you want to check for all False you need:
not any(...)
assert not any([False, True, False])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
Upvotes: 1