From a49b813885ec10ba0e22b86433943250278a341f Mon Sep 17 00:00:00 2001 From: Satellite QE <115476073+Satellite-QE@users.noreply.github.com> Date: Wed, 10 Jul 2024 04:09:33 -0400 Subject: [PATCH] [6.15.z] Add pytest option to randomly select and run number/percentage of tests from the collection. (#15554) Co-authored-by: Jameer Pathan <21165044+jameerpathan111@users.noreply.github.com> --- conftest.py | 1 + pytest_plugins/select_random_tests.py | 69 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 pytest_plugins/select_random_tests.py diff --git a/conftest.py b/conftest.py index cdc924e9063..edadc4d6008 100644 --- a/conftest.py +++ b/conftest.py @@ -23,6 +23,7 @@ 'pytest_plugins.sanity_plugin', 'pytest_plugins.video_cleanup', 'pytest_plugins.jira_comments', + 'pytest_plugins.select_random_tests', 'pytest_plugins.capsule_n-minus', # Fixtures 'pytest_fixtures.core.broker', diff --git a/pytest_plugins/select_random_tests.py b/pytest_plugins/select_random_tests.py new file mode 100644 index 00000000000..67dec7b7b4b --- /dev/null +++ b/pytest_plugins/select_random_tests.py @@ -0,0 +1,69 @@ +import math +import random + +from fauxfactory import gen_string +import pytest + +from robottelo.logging import logger + + +def pytest_addoption(parser): + """Add --select-random-tests option to select and run N random tests from the selected test collection. + Examples: + pytest tests/foreman/ --select-random-tests 4 --random-seed fksdjn + pytest tests/foreman/ --select-random-tests '5%' + """ + parser.addoption( + '--select-random-tests', + action='store', + default=0, + help='Number/Percentage of tests to randomly select and run from selected test collection. \n ' + 'To re-run same collection later, provide seed value using --random-seed. ' + 'OR check robottelo.log to get the seed value that was generated randomly.', + ) + parser.addoption( + '--random-seed', + action='store', + default=gen_string('alpha'), + help='Seed value for random test collection. Should be used with --select-random-tests option.', + ) + + +def pytest_configure(config): + """Register select_random_tests and random_seed markers to avoid warnings.""" + markers = [ + 'select_random_tests: Number/Percentage of tests to randomly select and run.', + 'random_seed: Seed value for random test collection.', + ] + for marker in markers: + config.addinivalue_line('markers', marker) + + +@pytest.hookimpl(trylast=True) +def pytest_collection_modifyitems(items, config): + """Modify test collection to select and run N random tests from the selected test collection.""" + select_random_tests = config.getoption('select_random_tests') + random_seed = config.getoption('random_seed') + if select_random_tests: + select_random_tests = ( + math.ceil(len(items) * float(select_random_tests.split('%')[0]) / 100) + if '%' in select_random_tests + else int(select_random_tests) + ) + try: + random.seed(random_seed) + selected = random.sample(items, k=select_random_tests) + except ValueError as err: + logger.warning( + 'Number of tests to select randomly are greater than the tests in the selected collection. ' + f'Tests collected: {len(items)}, Tests to select randomly: {select_random_tests}, Seed value: {random_seed}' + ) + raise err + logger.info( + 'Modifying test collection based on --select-random-tests pytest option. ' + f'Tests collected: {len(items)}, Tests to select randomly: {select_random_tests}, Seed value: {random_seed}' + ) + deselected = [item for item in items if item not in selected] + # selected will be empty if no filter option was passed, defaulting to full items list + items[:] = selected if deselected else items + config.hook.pytest_deselected(items=deselected)