Search code examples
python-3.xpython-requestspytestfixtures

CLI arguments are not processed in conftest.py in my pytest


My project implementation is to capture details from CLI to determine the environment, to generate the token in that environment and to return the token and the application URL.

Here is the code in conftest.py file

def pytest_addoption(parser):
parser.addoption('--env',
                 dest='testenv',
                 choices=["qa","aws","prod"],
                 default='qa',
                 help='Specify environment: "qa", "aws", "prod".')

@pytest.fixture(scope='session')
#def conftest_setup(request):
  #  env = request.config.getoption("--env")

def conftest_setup(request):
    env = request.config.getoption("--env")
    print(env)
    if (env =='aws'):
        url='AWSURL'
    elif ( env =='prod'):
        url='prodURL'
    else:
        url='QAURL'

    token = requests.post(auth=HTTPBasicAuth(clientID, secret),headers=tokenheaders, data=payload)
    auth = token.json()['access_token']
    return auth,url

test_service.py has

auth1=''
url1=''

def initialCall(conftest_setup):
    auth1=conftest_setup[1]  # Pretty sure this is wrong, but couldnt get a way to retrieve this
    url1=conftest_setup[2]


# Now I want to use the auth1 and url1 obtained from above method to the below method
def response():
    print("auth is " ,auth1)
    print("URL is " ,url1)
    headers = {'content-type': 'application/json',
              'Authorization' : auth1}
    response= 
        (requests.post(url1,data=json.dumps(data1),headers=headers)).json()

Currently, I get this exception

request = <FixtureRequest for <Function 

>   ???

test\test_service_1.py:41:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\software\python\lib\site-packages\pytest_bdd\scenario.py:195: in _execute_scenario
    _execute_step_function(request, scenario, step, step_func)
..\..\software\python\lib\site-packages\pytest_bdd\scenario.py:136: in _execute_step_function
    step_func(**kwargs)
..\..\software\python\lib\site-packages\pytest_bdd\steps.py:164: in step_func
    result = request.getfixturevalue(func.__name__)
..\..\software\python\lib\site-packages\_pytest\fixtures.py:478: in getfixturevalue
    return self._get_active_fixturedef(argname).cached_result[0]
..\..\software\python\lib\site-packages\_pytest\fixtures.py:501: in _get_active_fixturedef
    self._compute_fixture_value(fixturedef)
..\..\software\python\lib\site-packages\_pytest\fixtures.py:586: in _compute_fixture_value
    fixturedef.execute(request=subrequest)
..\..\software\python\lib\site-packages\_pytest\fixtures.py:895: in execute
    return hook.pytest_fixture_setup(fixturedef=self, request=request)
..\..\software\python\lib\site-packages\pluggy\hooks.py:289: in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
..\..\software\python\lib\site-packages\pluggy\manager.py:68: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
..\..\software\python\lib\site-packages\pluggy\manager.py:62: in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
..\..\software\python\lib\site-packages\_pytest\fixtures.py:937: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
..\..\software\python\lib\site-packages\_pytest\fixtures.py:794: in call_fixture_func
    res = fixturefunc(**kwargs)



 ***test\test_service_1.py:40: in testws_response
        response=(requests.post(url1,data=json.dumps(data1),headers=headers)).json()***


..\..\software\python\lib\site-packages\requests\api.py:116: in post
    return request('post', url, data=data, json=json, **kwargs)
..\..\software\python\lib\site-packages\requests\api.py:60: in request
    return session.request(method=method, url=url, **kwargs)
..\..\software\python\lib\site-packages\requests\sessions.py:519: in request
    prep = self.prepare_request(req)
..\..\software\python\lib\site-packages\requests\sessions.py:462: in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
..\..\software\python\lib\site-packages\requests\models.py:313: in prepare
    self.prepare_url(url, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <PreparedRequest [POST]>, url = '', params = OrderedDict()

    def prepare_url(self, url, params):
        """Prepares the given HTTP URL."""
        #: Accept objects that have string representations.
        #: We're unable to blindly call unicode/str functions
        #: as this will include the bytestring indicator (b'')
        #: on python 3.x.
        #: https://github.com/requests/requests/pull/2238
        if isinstance(url, bytes):
            url = url.decode('utf8')
        else:
            url = unicode(url) if is_py2 else str(url)

        # Remove leading whitespaces from url
        url = url.lstrip()

        # Don't do any URL preparation for non-HTTP schemes like `mailto`,
        # `data` etc to work around exceptions from `url_parse`, which
        # handles RFC 3986 only.
        if ':' in url and not url.lower().startswith('http'):
            self.url = url
            return

        # Support for unicode domain names and paths.
        try:
            scheme, auth, host, port, path, query, fragment = parse_url(url)
        except LocationParseError as e:
            raise InvalidURL(*e.args)

        if not scheme:
            error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?")
            error = error.format(to_native_string(url, 'utf8'))

>           raise MissingSchema(error)
E           requests.exceptions.MissingSchema: Invalid URL '': No schema supplied. Perhaps you meant http://?

..\..\software\python\lib\site-packages\requests\models.py:387: MissingSchema

No console output observed for print(env) in conftest.py file while auth is None URL IS None are observed for print statements in test_service

CLI execution throws error when I pass pytest -s --env='qa' but is acceptable for pytest -s --env=qa. So the CLI arguments are captured.

Please help me to capture the auth and url from conftest.py across the test file.

Also, is there a way I can use this auth,url returned from conftest.py to use across multiple test files?


Solution

  • Many thanks to @hoefling for providing valuable insights.

    I've added/updated the fixture in the following places and declared auth1 and url1 as global inside initialcall method. It now works as expected.

    test_service.py has

    @pytest.fixture(autouse=True, scope='session')
    def initialCall(conftest_setup):
        global auth1,AN_API1
        auth1 = conftest_setup[0]
        AN_API1=conftest_setup[1]
    

    conftest.py has

    @pytest.fixture(autouse=True,scope='session')
    def conftest_setup(request):