Не понимаю assertRaises с генераторами + unittest - PullRequest
0 голосов
/ 26 марта 2020

Я не понимаю, что не так. Вот 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 с почти такими же результатами. Сделал шаблон выше, чтобы воспроизвести проблему с простым кодом.

...