1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
import random
import sys
import traceback
import warnings
import pytest
from random_order.bucket_types import bucket_type_keys, bucket_types
from random_order.cache import process_failed_first_last_failed
from random_order.config import Config
from random_order.shuffler import _disable, _get_set_of_item_ids, _shuffle_items
from random_order.xdist import XdistHooks
def pytest_addoption(parser):
group = parser.getgroup('pytest-random-order options')
group.addoption(
'--random-order',
action='store_true',
dest='random_order_enabled',
help='Randomise test order (by default, it is disabled) with default configuration.',
)
group.addoption(
'--random-order-bucket',
action='store',
dest='random_order_bucket',
default=Config.default_value('module'),
choices=bucket_types,
help='Randomise test order within specified test buckets.',
)
group.addoption(
'--random-order-seed',
action='store',
dest='random_order_seed',
default=Config.default_value(str(random.randint(1, 1000000))),
help='Randomise test order using a specific seed.',
)
def pytest_configure(config):
config.addinivalue_line(
'markers',
'random_order(disabled=True): disable reordering of tests within a module or class'
)
if config.pluginmanager.hasplugin('xdist'):
config.pluginmanager.register(XdistHooks())
if hasattr(config, 'workerinput'):
# pytest-xdist: use seed generated on main.
seed = config.workerinput['random_order_seed']
if hasattr(config, 'cache'):
assert config.cache is not None
config.cache.set('random_order_seed', seed)
config.option.random_order_seed = seed
def pytest_report_header(config):
plugin = Config(config)
if not plugin.is_enabled:
return "Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>"
return (
'Using --random-order-bucket={plugin.bucket_type}\n'
'Using --random-order-seed={plugin.seed}\n'
).format(plugin=plugin)
def pytest_collection_modifyitems(session, config, items):
failure = None
session.random_order_bucket_type_key_handlers = []
process_failed_first_last_failed(session, config, items)
item_ids = _get_set_of_item_ids(items)
plugin = Config(config)
try:
seed = plugin.seed
bucket_type = plugin.bucket_type
if bucket_type != 'none':
_shuffle_items(
items,
bucket_key=bucket_type_keys[bucket_type],
disable=_disable,
seed=seed,
session=session,
)
except Exception as e:
# See the finally block -- we only fail if we have lost user's tests.
_, _, exc_tb = sys.exc_info()
failure = 'pytest-random-order plugin has failed with {0!r}:\n{1}'.format(
e, ''.join(traceback.format_tb(exc_tb, 10))
)
if not hasattr(pytest, "PytestWarning"):
config.warn(0, failure, None)
else:
warnings.warn(pytest.PytestWarning(failure))
finally:
# Fail only if we have lost user's tests
if item_ids != _get_set_of_item_ids(items):
if not failure:
failure = 'pytest-random-order plugin has failed miserably'
raise RuntimeError(failure)
|