简介:
pytest-random-order插件允许用户按随机顺序执行测试,它提供包括module,class,package以及global等不同粒度的随机性,并且允许用户使用mark标记特定粒度的测试集,从而保证部分test cases的执行顺序不被更改,具有高度灵活性。
GitHub地址: https://github.com/jbasko/pytest-random-order
源码解析:
主要介绍plugin这个module,直接与pytest插件开发相关。
random_order/plugin.py:
pytest_addoption: Hook function, 这里创建了一个argparser的group,通过addoption方法添加option,使得显示help信息时相关option显示在一个group下面,更加友好。
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.',
)
pytest_report_header:Hook function,在这里给出插件运行的相关信息,方便出行问题时定位和复现问题。
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)
pytest_collection_modifyitems: Hook function, 在测试项收集完以后执行,用于过滤或者重排测试项。
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)