-
Notifications
You must be signed in to change notification settings - Fork 106
Closed
Description
Hi, I saw something related in the docs:
when using an iterator or a generator, all the items will be loaded into memory before the start of the test run
https://github.com/wolever/parameterized#exhaustive-usage-examples
Not sure if this deserves a separate mention or a warning in code. Sorry if this is a known issue, and I couldn't find it.
The Problem: “Consumables” (e.g. iterators) declared in non-parameterized decorators that are used by one test case remain consumed for other test cases.
Reproduction:
from parameterized import parameterized
from unittest import mock, TestCase
class MyIterator:
def get_iterator(self):
raise NotImplementedError
class TestConsumableInOtherDecorator(TestCase):
@parameterized.expand(
[('first run',), ('second run',)]
)
@mock.patch.object(MyIterator, 'get_iterator', new=mock.Mock(return_value=iter([1])))
def test_the_problem(self, case):
print(case)
assert list(MyIterator.get_iterator()) == [1]
@parameterized.expand(
[('first run',), ('second run',)]
)
@mock.patch.object(MyIterator, 'get_iterator', new=mock.Mock(return_value=[1]))
def test_isolating_the_problem(self, case):
print(case)
assert list(MyIterator.get_iterator()) == [1]
@parameterized.expand(
[('first run',), ('second run',)]
)
@mock.patch.object(MyIterator, 'get_iterator')
def test_the_workaround(self, case, mock_get_iterator):
mock_get_iterator.return_value = iter([1])
print(case)
assert list(MyIterator.get_iterator()) == [1]
Output:
$ python -m unittest -v test.py
test_isolating_the_problem_0_first_run (test.TestConsumableInOtherDecorator) ... first run
ok
test_isolating_the_problem_1_second_run (test.TestConsumableInOtherDecorator) ... second run
ok
test_the_problem_0_first_run (test.TestConsumableInOtherDecorator) ... first run
ok
test_the_problem_1_second_run (test.TestConsumableInOtherDecorator) ... second run
FAIL
test_the_workaround_0_first_run (test.TestConsumableInOtherDecorator) ... first run
ok
test_the_workaround_1_second_run (test.TestConsumableInOtherDecorator) ... second run
ok
======================================================================
FAIL: test_the_problem_1_second_run (test.TestConsumableInOtherDecorator)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/google/home/hartunian/Desktop/lib/python3.10/site-packages/parameterized/parameterized.py", line 533, in standalone_func
return func(*(a + p.args), **p.kwargs)
File "/usr/lib/python3.10/unittest/mock.py", line 1379, in patched
return func(*newargs, **newkeywargs)
File "/usr/local/google/home/hartunian/Desktop/lib/python3.10/site-packages/parameterized/parameterized.py", line 81, in dummy_func
return orgfunc(*args, **kwargs)
File "/usr/lib/python3.10/unittest/mock.py", line 1379, in patched
return func(*newargs, **newkeywargs)
File "/usr/local/google/home/hartunian/Desktop/test.py", line 17, in test_the_problem
assert list(MyIterator.get_iterator()) == [1]
AssertionError
We're fine with the workaround but just wanted to raise awareness.
Thanks!
Metadata
Metadata
Assignees
Labels
No labels