Python 3.x 不了解带生成器的assertRaises+;单元测试
我不明白怎么了。这里有两个简单的范围生成器。两者都会使输入值误差大于最大值。第一个是生成器理解,第二个是使用收益率Python 3.x 不了解带生成器的assertRaises+;单元测试,python-3.x,unit-testing,generator,raise,Python 3.x,Unit Testing,Generator,Raise,我不明白怎么了。这里有两个简单的范围生成器。两者都会使输入值误差大于最大值。第一个是生成器理解,第二个是使用收益率 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
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()
这正是我们想要的。
现在进行一些unittest测试,以确保实际引发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()
使用生成器理解的测试会产生错误,但使用屈服的生成器不会。一旦我删除了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上稍微复杂一点的代码开始,结果基本相同。制作上面的样板以在简单的代码上重现问题。这种看似不一致的行为的原因如下:
是一个发生器功能test\u产量
是一个返回生成器的函数test\u compr
test\u compr
时,函数体将立即执行,并作为其结果返回一个生成器(或抛出)
相反,当您调用test\u yield
时,您会收到一个生成器对象。生成器的执行不会在创建时开始,而是在第一次调用next
函数时开始。因此,您的测试函数应该如下所示:
def test_exception(self):
with self.assertRaises(ValueError) as c:
g = test_yield(N_BIG)
next(g)
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)
def test_exception(self):
with self.assertRaises(ValueError) as c:
g = test_yield(N_BIG)
next(g)