Skip to content

Commit

Permalink
Remove --randomly-repeat-last in favour of --randomly-seed=last
Browse files Browse the repository at this point in the history
Change the design from #164.
  • Loading branch information
adamchainz committed Mar 1, 2019
1 parent c9bb60e commit 7f32ed3
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
3 changes: 3 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Pending Release

.. Insert new release notes below this line
* Add the option ``--randomly-seed=last`` to reuse the last used value for the
seed.

2.0.0 (2019-02-28)
------------------

Expand Down
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ them with that seed using the flag as suggested:
pytest --randomly-seed=1234
Or more conveniently, use the special value ``last``:

.. code-block:: bash
pytest --randomly-seed=last
Since the ordering is by module, then by class, you can debug inter-test
pollution failures by narrowing down which tests are being run to find the bad
interaction by rerunning just the module/class:
Expand Down
42 changes: 26 additions & 16 deletions pytest_randomly.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import random
import time

Expand Down Expand Up @@ -31,17 +32,29 @@
__version__ = '2.0.0'


default_seed = int(time.time())


def seed_type(string):
if string == 'last':
return string
try:
return int(string)
except ValueError:
raise argparse.ArgumentTypeError(
"{} is not an integer or the string 'last'".format(repr(string))
)


def pytest_addoption(parser):
group = parser.getgroup('randomly', 'Randomizes tests')
group._addoption(
'--randomly-repeat-last', action='store_true', dest='randomly_repeat_last',
help="""Set the seed to the previous run's seed."""
)
group._addoption(
'--randomly-seed', action='store', dest='randomly_seed',
default=int(time.time()), type=int,
help="""Set the seed that pytest-randomly uses. Default behaviour:
use time.time()"""
default=str(default_seed), type=seed_type,
help="""Set the seed that pytest-randomly uses (int), or pass the
special value 'last' to reuse the seed from the previous run.
Default behaviour: use int(time.time()), so the seed is
different on each run."""
)
group._addoption(
'--randomly-dont-reset-seed', action='store_false',
Expand Down Expand Up @@ -83,18 +96,15 @@ def _reseed(config, offset=0):
np_random.set_state(np_random_states[seed])


def pytest_configure(config):
if config.option.randomly_repeat_last and config.cache.get('last_seed', None):
seed = config.cache.get('last_seed', None)
def pytest_report_header(config):
seed_value = config.getoption('randomly_seed')
if seed_value == 'last':
seed = config.cache.get('randomly_seed', default_seed)
else:
seed = config.getoption('randomly_seed')
config.cache.set('last_seed', seed)
seed = seed_value
config.cache.set('randomly_seed', seed)
config.option.randomly_seed = seed


def pytest_report_header(config):
_reseed(config)
seed = config.getoption('randomly_seed')
return "Using --randomly-seed={0}".format(seed)


Expand Down
34 changes: 23 additions & 11 deletions tests/test_it.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,38 +70,50 @@ def test_b():
out.assert_outcomes(passed=2, failed=0)


def test_it_reuses_the_prev_run_seed(ourtestdir):
"""
Run a test that exercises the randomly-repeat-last option.
"""
def test_using_last_seed(ourtestdir):
ourtestdir.makepyfile(
test_one="""
def test_a():
pass
"""
)
out = ourtestdir.runpytest('--randomly-seed=33')
out = ourtestdir.runpytest()
out.assert_outcomes(passed=1, failed=0)
out.stdout.fnmatch_lines(['Using --randomly-seed=33'])
seed_line = [x for x in out.stdout.lines if x.startswith('Using --randomly-seed=')][0]

out = ourtestdir.runpytest('--randomly-seed=last')
out.assert_outcomes(passed=1, failed=0)
out.stdout.fnmatch_lines([seed_line])


def test_using_last_explicit_seed(ourtestdir):
ourtestdir.makepyfile(
test_one="""
def test_a():
pass
"""
)
out = ourtestdir.runpytest('--randomly-repeat-last')
out = ourtestdir.runpytest('--randomly-seed=33')
out.assert_outcomes(passed=1, failed=0)
out.stdout.fnmatch_lines(['Using --randomly-seed=33'])

out = ourtestdir.runpytest('--randomly-seed=last')
out.assert_outcomes(passed=1, failed=0)
out.stdout.fnmatch_lines(['Using --randomly-seed=33'])


def test_passing_nonsense_for_randomly_seed(ourtestdir):
ourtestdir.makepyfile(
test_one="""
def test_a():
pass
"""
)
out = ourtestdir.runpytest()
out.assert_outcomes(passed=1, failed=0)
for line in out.outlines:
assert 'Using --randomly-seed=33' not in line
out = ourtestdir.runpytest('--randomly-seed=invalidvalue')
assert out.ret != 0
out.stderr.fnmatch_lines([
"pytest.py: error: argument --randomly-seed: 'invalidvalue' is not an integer or the string 'last'"
])


def test_it_resets_the_random_seed_at_the_start_of_test_classes(ourtestdir):
Expand Down

0 comments on commit 7f32ed3

Please sign in to comment.