【问题标题】:CLI arguments are not processed in conftest.py in my pytest在我的 pytest 中的 conftest.py 中未处理 CLI 参数
【发布时间】:2019-06-02 22:45:00
【问题描述】:

我的项目实现是从 CLI 捕获详细信息以确定环境,在该环境中生成令牌并返回令牌和应用程序 URL。

这是 conftest.py 文件中的代码

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 有

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()

目前,我得到了这个异常

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

在 conftest.py 文件中没有观察到 print(env) 的控制台输出,而 身份验证是无 网址为无 在 test_service 中观察打印语句

当我通过 pytest -s --env='qa' 时,CLI 执行会引发错误,但 pytest -s --env=qa 可以接受。因此 CLI 参数被捕获。

请帮助我从测试文件中的 conftest.py 中捕获 auth 和 url。

另外,有没有办法可以使用从 conftest.py 返回的这个 auth,url 来跨多个测试文件使用?

【问题讨论】:

  • 异常只是说您的 URL 没有有效的方案,例如它是 www.example.com 而不是 https://www.example.com
  • 感谢@hoefling 的回复。我尝试了提到的 URL,但仍然看到问题。我想知道为什么 conftest.py 中的打印语句没有执行。 URL1 和 auth 值在 test_service.py 中显示为 None
  • 啊,我明白了。 initialCall 不是固定装置,也不会在任何地方调用。用@pytest.fixture(autouse=True)装饰它,它会在每次测试前由pytest执行;或用@pytest.fixture(autouse=True, scope='session')pytest 装饰将在所有测试之前执行一次。
  • 另一件事是Python从零开始计数,所以通过conftest_setup[0]访问auth,通过conftest_setup[1]访问url。
  • 一般来说,虽然您使用全局变量的方法没有错,但我宁愿声明单独的装置 auth 返回 conftest_setup[0]url 返回 conftest_setup[1] 并在必要时在测试中使用它们。我什至会将代码从 conftest_setup 移到这两个固定装置中,以清楚地将两者分开。

标签: python-3.x python-requests pytest fixtures


【解决方案1】:

非常感谢 @hoefling 提供宝贵的见解。

我已在以下位置添加/更新了夹具,并将 auth1 和 url1 声明为在 initialcall 方法中的全局。它现在按预期工作。

test_service.py 有

@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 有

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

【讨论】:

    猜你喜欢
    • 2023-01-11
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多