Я не понимаю, что не так. Вот 2 простых генератора диапазона. Оба вызывают ValueError на входе больше, чем MAX. Первый - это понимание генератора, а второй - доходность.
MSG = 'Wrong number'
MAX = 20
def test_compr(n, m=MAX):
if n > m:
raise ValueError('{} {} in {}'.format(MSG, n, test_compr.__name__))
return (i for i in range(n))
def test_yield(n, m=MAX):
if n > m:
raise ValueError('{} {} in {}'.format(MSG, n, test_yield.__name__))
i = 0
while i < n:
yield i
i += 1
def main():
n = 30
try:
print(list(test_compr(n)))
except ValueError as e:
print(e)
try:
print(list(test_yield(n)))
except ValueError as e:
print(e)
if __name__ == '__main__':
main()
python3 --version && python t.py
Python 3.7.5
Wrong number 30 in test_compr
Wrong number 30 in test_yield
Работает как задумано. Теперь некоторые тесты юнит-тестов, чтобы убедиться, что ValueError действительно вызван.
import unittest
from t import test_compr, test_yield
N_BIG = 30
N_OK = 19
# test generator comprehension
class TestCompr(unittest.TestCase):
def test_ok(self):
tst = N_OK
g = test_compr(tst)
for num in range(tst):
self.assertEqual(num, next(g))
def test_exception(self):
TST = N_BIG
with self.assertRaises(ValueError) as c:
test_compr(N_BIG)
# test yield
class TestYield(unittest.TestCase):
def test_ok(self):
tst = N_OK
g = test_yield(tst)
for num in range(tst):
self.assertEqual(num, next(g))
def test_exception(self):
tst=N_BIG
with self.assertRaises(ValueError) as c:
test_yield(tst)
if __name__ == '__main__':
unittest.main()
> python3 tests.py
Python 3.7.5
..F.
======================================================================
FAIL: test_exception (__main__.TestYield)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests.py", line 31, in test_exception
test_yield(tst)
AssertionError: ValueError not raised
----------------------------------------------------------------------
Ran 4 tests in 0.001s
FAILED (failures=1)
Тест с пониманием генератора вызывает ошибку, а генератор с выходом - нет. Как только я удаляю yield, я вижу, что unittest выдает правильный результат на assertRaises
Пытался установить последнюю python. Та же проблема.
python3.8 --version && python3.8 tests.py
Python 3.8.0
..F.
======================================================================
FAIL: test_exception (__main__.TestYield)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests.py", line 31, in test_exception
test_yield(tst)
AssertionError: ValueError not raised
----------------------------------------------------------------------
Ran 4 tests in 0.001s
FAILED (failures=1)
Не уверен, что не так и как это исправить. Я начал с немного более сложного кода на python3 .5 с почти такими же результатами. Сделал шаблон выше, чтобы воспроизвести проблему с простым кодом.