-1

Have to fetch the command line arguments and assign them to global variables in the python script under nontest modules using a pytest.

Example Code:

# conftest.py
def pytest_addoption(parser):
    parser.addoption("--name", action="store", default="default name")
# test_sample.py
import pytest

@pytest.fixture
def name(req):
    return req.getoption("name")

# Here, I require the command line argument assigned to a global variable "glob_name"
glob_name = name

foo="""
def test_"""+glob_name+"""():
    print("Inside test function with a global name")
"""
exec(foo)

Command Used:

pytest -q -s test_sample.py --name google

Error occurred:

========================================================================================== ERRORS ==========================================================================================
_____________________________________________________________________________ ERROR collecting test_sample.py ______________________________________________________________________________
test_sample.py:10: in <module>
    def test_"""+glob_name+"""():
E   TypeError: cannot concatenate 'str' and 'function' objects
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1 error in 0.12 seconds

Expected Output:

It should have to append the str "google" to the test function name and have to execute that function.

I would appreciate it if anyone can revert back with a solution for the above-mentioned issue.

user6677473
  • 169
  • 1
  • 1
  • 8

1 Answers1

1

To achieve what you are asking require us to use two hooks at same time.

  1. pytest_generate_tests : To implement your own parametrization scheme.
  2. pytest_collection_modifyitems : To rename based on your requirement.

You can use below code for same

conftest.py

import pytest


def pytest_addoption(parser):
    parser.addoption("--name", action="store", default="default name")


@pytest.fixture(scope='session')
def get_name(request):
    return request.config.getoption("--name")


def pytest_generate_tests(metafunc):
    if "get_name" in metafunc.fixturenames:
        if metafunc.config.getoption("name"):
            param = str(metafunc.config.getoption("name"))
        else:
            param = "default"
        metafunc.parametrize("get_name", [param])


def pytest_collection_modifyitems(items):
    for item in items:
        # check that we are altering a test named `test_run_name`
        # and it accepts the `get_name` arg
        if item.originalname == 'test_run_name' and 'get_name' in item.fixturenames:
            item._nodeid = item.nodeid.replace(']', '').replace('run_name[', '')

test_sample.py

def test_run_name(get_name):
    print("Inside test function with a global name {}".format(get_name))
    assert True

Run using cmd

pytest -v -s test_sample.py --name google

Output in Console:

enter image description here

alpha89
  • 306
  • 2
  • 7