pytest-bdd icon indicating copy to clipboard operation
pytest-bdd copied to clipboard

Exception in scenario.py when executing tests in parallel threads

Open KrystianOcado opened this issue 5 years ago • 2 comments
trafficstars

Hi!

I would like to report an issue in pytest-bdd:

pytest-bdd 3.2.1 pytest 5.4.1 Python 3.7.5

When executing tests in parallel threads, for example using using threads pytest-parallel, a race condition can occur in file pytest_bdd/scenario.py function find_argumented_step_fixture_name:

name = 'foobar'
type_ = 'given'
fixturemanager = <_pytest.fixtures.FixtureManager object at 0x7f8d6f0a4bd0>
request = <FixtureRequest for <Function foobar>>
    def find_argumented_step_fixture_name(name, type_, fixturemanager, request=None):
        """Find argumented step fixture name."""
        # happens to be that _arg2fixturedefs is changed during the iteration so we use a copy
>       for fixturename, fixturedefs in list(fixturemanager._arg2fixturedefs.items()):
E       RuntimeError: dictionary changed size during iteration
/lib/python3.7/site-packages/pytest_bdd/scenario.py:51: RuntimeError

It seems that what happens is, while a copy of dictionary is created here: list(fixturemanager._arg2fixturedefs.items()) fixture dictionary changes.

This can only be reproduced using Python 3, because dict.items() returns an iterator in Python 3, not a list of keys like in Python 2.

This issue should not appear in pytest-xdist because it uses multiprocessing.

I looked around and this code could use dict.copy().items(), instead of list(dict.items()), which should be thread-safe.

I understand that pytest-parallel might not be officially supported in pytest-bdd, but it would still be good to fix this issue.

I can fix it, but reproducing it consistently in test environment is really hard, so it would be hard to prove my fix.

KrystianOcado avatar Apr 23 '20 13:04 KrystianOcado

Possibly related to https://bugs.python.org/issue40327. @KrystianOcado, can you provide an mcve to reproduce the issue? It's fine if it doesn't always show, as long as one in many runs of the example shows it.

youtux avatar Apr 23 '20 18:04 youtux

I have run some tests with:

pytest-bdd 4.02 pytest-parallel 0.1.0

Tests are executed nicely, but then it hangs.

jruizaranguren avatar Jan 15 '21 12:01 jruizaranguren

KrystianOcado - can you please tell me how did you implement pytest-parallel to execute pytest-bdd tests in parallel?

Enigmaderockz avatar Nov 19 '22 19:11 Enigmaderockz

Hi @youtux !

Sorry I missed your message. I'm unable to provide mvce, even tough I tried. I was not able to reproduce it a fresh project. It looks like I was the only one to experience it, so I will close this issue. Sorry again and thanks!

HI @Enigmaderockz !

Dependencies:

pytest-bdd = "==6.0.0"
pytest-parallel = "==0.1.1"

pytest.ini

addopts =
    --workers=1
    --tests-per-worker=20

KrystianOcado avatar Nov 22 '22 18:11 KrystianOcado

thanks @KrystianOcado . can you please tell me what command you are using to run pytest-bdd test cases parallely using pytest-parallel? I am using pytest-bdd -sv test_filename.py.

Enigmaderockz avatar Dec 07 '22 18:12 Enigmaderockz

Hi @Enigmaderockz !

I use pytest command to run tests.

KrystianOcado avatar Dec 08 '22 13:12 KrystianOcado