Skip to content

Commit

Permalink
feature: add the option --randomly-seed-per-test to use a differe…
Browse files Browse the repository at this point in the history
…nt seed for each test
  • Loading branch information
brycedrennan committed Apr 10, 2024
1 parent c2e8e2f commit f61a6ea
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -2,6 +2,13 @@
Changelog
=========

3.16.0 (2024-04-09)
-------------------

* Add the option ``--randomly-seed-per-test`` to use a different seed for each test.

Resolves `Issue #600 <https://github.com/pytest-dev/pytest-randomly/issues/600>`__

3.15.0 (2023-08-15)
-------------------

Expand Down
3 changes: 3 additions & 0 deletions README.rst
Expand Up @@ -160,6 +160,9 @@ You can disable behaviours you don't like with the following flags:
the start of every test
* ``--randomly-dont-reorganize`` - turn off the shuffling of the order of tests

By default each test starts out with the same seed, if you'd like a different one
per test you can use the ``--randomly-seed-per-test`` flag.

The plugin appears to Pytest with the name 'randomly'. To disable it
altogether, you can use the ``-p`` argument, for example:

Expand Down
19 changes: 18 additions & 1 deletion src/pytest_randomly/__init__.py
Expand Up @@ -95,6 +95,15 @@ def pytest_addoption(parser: Parser) -> None:
Default behaviour: use random.Random().getrandbits(32), so the seed is
different on each run.""",
)
group._addoption(
"--randomly-seed-per-test",
action="store_true",
dest="randomly_seed_per_test",
default=False,
help="""Use a different seed for each test. Can be helpful for getting
different random data in each test, but still having reproducible
tests. Default behaviour: False.""",
)
group._addoption(
"--randomly-dont-reset-seed",
action="store_false",
Expand Down Expand Up @@ -209,9 +218,17 @@ def pytest_runtest_setup(item: Item) -> None:
_reseed(item.config, -1)


def seed_from_string(string: str) -> int:
return int(hashlib.md5(string.encode()).hexdigest(), 16)


def pytest_runtest_call(item: Item) -> None:
if item.config.getoption("randomly_reset_seed"):
_reseed(item.config)
if item.config.getoption("randomly_seed_per_test"):
test_offset = seed_from_string(item.nodeid) + 100
else:
test_offset = 0
_reseed(item.config, offset=test_offset)


def pytest_runtest_teardown(item: Item) -> None:
Expand Down
23 changes: 23 additions & 0 deletions tests/test_pytest_randomly.py
Expand Up @@ -82,6 +82,29 @@ def test_b():
out.assert_outcomes(passed=2, failed=0)


def test_it_can_use_different_random_seed_per_test(ourtester):
"""
Run a pair of tests that generate a number and assert they produce different numbers.
"""
ourtester.makepyfile(
test_one="""
import random
def test_a():
test_a.num = random.random()
if hasattr(test_b, 'num'):
assert test_a.num != test_b.num
def test_b():
test_b.num = random.random()
if hasattr(test_a, 'num'):
assert test_b.num != test_a.num
"""
)
out = ourtester.runpytest("--randomly-seed-per-test")
out.assert_outcomes(passed=2, failed=0)


def test_without_cacheprovider(ourtester):
ourtester.makepyfile(
test_one="""
Expand Down

0 comments on commit f61a6ea

Please sign in to comment.