繁体   English   中英

如何从pytest_addoptions访问pytest conftest中的命令行输入并将其用于夹具参数中?

[英]How do I access the command line input in pytest conftest from the pytest_addoptions and use it in fixture params?

我有一个conftest文件,用于在pytest中运行测试时处理硒驱动程序的设置和拆除。 我正在尝试添加命令行选项以确定我是否运行本地内置的selenium和Web驱动程序或远程selenium服务器和驱动程序等...

我添加了一个名为“ runenv”的命令行选项,并且试图从通过命令行输入的字符串值中获取字符串值,以确定系统是否应运行本地或远程Webdriver配置。 这使测试人员可以在自己的本地计算机上进行开发,但也意味着我们可以编写测试脚本,以将其作为构建管道的一部分在远程计算机上运行。

我的问题是以下文件中显示的parser.addoption未得到处理。 似乎没有返回我可以使用的值(无论是默认值还是通过命令行传递的值)。

我的conftest.py文件如下(*请注意,URL和远程IP只是用于保护公司隐私的示例)

#conftest.py

import pytest
import os
import rootdir_ref
import webdriverwrapper
from webdriverwrapper import DesiredCapabilities, FirefoxProfile



#when running tests from command line we should be able to pass --url=www..... for a different website, check what order these definitions need to be in
def pytest_addoption(parser):
    parser.addoption("--url", action="store", default="https://mydomain1.com.au")
    parser.addoption("--runenv", action="store", default="local")

@pytest.fixture(scope='session')
def url(request):
     return request.config.option.url

@pytest.fixture(scope='session')
def runenv(request):
     return request.config.option.runenv

BROWSERS = {}


if runenv == 'remote':
    BROWSERS = {'chrome_remote': DesiredCapabilities.CHROME}
else:
    BROWSERS = {'chrome': DesiredCapabilities.CHROME}



# BROWSERS = {
#     #'firefox': DesiredCapabilities.FIREFOX,
#     # 'chrome': DesiredCapabilities.CHROME,
#      'chrome_remote': DesiredCapabilities.CHROME,
#     # 'firefox_remote': DesiredCapabilities.FIREFOX
# }

@pytest.fixture(scope='function', params=BROWSERS.keys())
def browser(request):

    if request.param == 'firefox':
        firefox_capabilities = BROWSERS[request.param]
        firefox_capabilities['marionette'] = True
        firefox_capabilities['acceptInsecureCerts'] = True
        theRootDir = os.path.dirname(rootdir_ref.__file__)
        ffProfilePath = os.path.join(theRootDir, 'DriversAndTools', 'FirefoxSeleniumProfile')
        geckoDriverPath = os.path.join(theRootDir, 'DriversAndTools', 'geckodriver.exe')
        profile = FirefoxProfile(profile_directory=ffProfilePath)
       #  Testing with local Firefox Beta 56
        binary = 'C:\\Program Files\\Mozilla Firefox\\firefox.exe'
        b = webdriverwrapper.Firefox(firefox_binary=binary, firefox_profile=profile, capabilities=firefox_capabilities,
                                     executable_path=geckoDriverPath)

    elif request.param == 'chrome':
        desired_cap = BROWSERS[request.param]
        desired_cap['chromeOptions'] = {}
        desired_cap['chromeOptions']['args'] = ['--disable-plugins', '--disable-extensions']
        desired_cap['browserName'] = 'chrome'
        desired_cap['javascriptEnabled'] = True
        theRootDir = os.path.dirname(rootdir_ref.__file__)
        chromeDriverPath = os.path.join(theRootDir, 'DriversAndTools', 'chromedriver.exe')
        b = webdriverwrapper.Chrome(chromeDriverPath, desired_capabilities=desired_cap)

    elif request.param == 'chrome_remote':
        desired_cap = BROWSERS[request.param]
        desired_cap['chromeOptions'] = {}
        desired_cap['chromeOptions']['args'] = ['--disable-plugins', '--disable-extensions']
        desired_cap['browserName'] = 'chrome'
        desired_cap['javascriptEnabled'] = True
        b = webdriverwrapper.Remote(command_executor='http://192.168.1.1:4444/wd/hub', desired_capabilities=desired_cap)

    elif request.param == 'firefox_remote':
        firefox_capabilities = BROWSERS[request.param]
        firefox_capabilities['marionette'] = True
        firefox_capabilities['acceptInsecureCerts'] = True
        firefox_capabilities['browserName'] = 'firefox'
        firefox_capabilities['javascriptEnabled'] = True
        theRootDir = os.path.dirname(rootdir_ref.__file__)
        ffProfilePath = os.path.join(theRootDir, 'DriversAndTools', 'FirefoxSeleniumProfile')
        profile = FirefoxProfile(profile_directory=ffProfilePath)
        b = webdriverwrapper.Remote(command_executor='http://192.168.1.1:4444/wd/hub',
                                    desired_capabilities=firefox_capabilities, browser_profile=profile)

    else:
        b = BROWSERS[request.param]()
    request.addfinalizer(lambda *args: b.quit())

    return b


@pytest.fixture(scope='function')
def driver(browser, url):
    driver = browser
    driver.set_window_size(1260, 1080)
    driver.get(url)
    return driver

在conftest设置页面之后,我的测试将仅利用生成的“驱动程序”固定装置。 测试示例可能是:

import pytest
from testtools import login, dashboard, calendar_helper, csvreadtool, credentials_helper
import time

@pytest.mark.usefixtures("driver")
def test_new_appointment(driver):

    testId = 'Calendar01'
    credentials_list = credentials_helper.get_csv_data('LoginDetails.csv', testId)

    # login
    assert driver.title == 'Patient Management cloud solution'
    rslt = login.login_user(driver, credentials_list)
.... etc..

然后,我想使用以下命令运行测试套件:python -m pytest -v --html =。\\ Results \\ testrunX.html --self-contained-html --url = https://myotherdomain.com .au / --runenv = chrome_remote

到目前为止,url命令行选项有效,我可以使用它来覆盖url或使用默认值。

但是我无法从runenv命令行选项获取值。 在下面的if语句中,它将始终默认为else语句。 即使我对该parser.addoption的默认设置为'local',runenv似乎也没有值。

if runenv == 'remote':
    BROWSERS = {'chrome_remote': DesiredCapabilities.CHROME}
else:
    BROWSERS = {'chrome': DesiredCapabilities.CHROME}

我尝试在if语句之前放入pdb.trace(),以便可以看到runenv中的内容,但是它只会告诉我这是一个函数,而且我似乎无法从中获取值,这使得我认为这里根本没有人烟。

我不确定如何调试conftest文件,因为输出通常不会出现在控制台输出中。 有什么建议么? pytest_addoption实际上接受2个或更多自定义命令行参数吗?

我在Windows 10的VirtualEnv中使用Python 3.5.3 Pytest 3.2.1

在这里,为什么要使用urlrunenv作为灯具? 您可以如下使用它:

在你的conftest.py中

def pytest_addoption(parser):
    parser.addoption('--url', action='store', default='https://mytestdomain.com.au/', help='target machine url')
    parser.addoption('--runenv', action='store', default='remote', help='select remote or local')

def pytest_configure(config):
        os.environ["url"] = config.getoption('url') 
        os.environ["runenv"] = config.getoption('runenv') 

现在,无论您要访问urlrunenv哪里, runenv需要编写os.getenv('Variable_name')

@pytest.fixture(scope='function')
def driver(browser):
    driver = browser
    driver.set_window_size(1260, 1080)
    driver.get(os.getenv('url'))
    return driver

或者像您的代码中一样

if os.getenv('runenv')== 'remote':
    BROWSERS = {'chrome_remote': DesiredCapabilities.CHROME}
else:
    BROWSERS = {'chrome': DesiredCapabilities.CHROME}

在这里,url和runenv将保存在OS环境变量中,并且您可以仅通过os.getenv()就可以在没有固定装置的情况下访问它

希望对你有帮助!

BROWSERS器在conftest.py 导入时填充,而在导入时runenv是一个函数。 如果要将runenv用作固定装置, BROWSERS也必须是固定装置:

@pytest.fixture(scope='session')
def BROWSERS(runenv):
    if runenv == 'remote':
        return {'chrome_remote': DesiredCapabilities.CHROME}
    else:
        return {'chrome': DesiredCapabilities.CHROME}

好的,在做完概念验证之后,看来我问题的主要部分是我无法使用命令行选项来更改函数(夹具或非夹具函数)的输出,然后将其用作另一个请求夹具功能上的动态参数列表。 在阅读了有关它的内容之后,似乎与加载夹具功能期间的处理顺序有关。 除了玩metafunc之外,我几乎尝试了所有其他方法。

我尝试使用所有各种pytest.mark.fixture或params =部分中的任何变体,它们根本不会产生可迭代的列表(在某些情况下,我可以将其提供给我整个列表,但不会对其进行迭代)

我也尝试过lazyfixture模型,但没有成功。

我尝试在夹具功能中使用字典作为输出。 我在函数外尝试了它们,我对类进行了同样的尝试,并在夹具函数内创建了填充对象。 我尝试在params =中使用pytest.mark.getfixturevalue,尝试使用pytest.mark.use装饰器,尝试了参数化装饰器。 这些都不起作用。

似乎唯一可行的方法是在此处提出尚未实际开发的替代解决方案。 https://docs.pytest.org/en/latest/proposals/parametrize_with_fixtures.html

最后,我决定将所有逻辑都包含在一个大型Fixture函数中,该函数似乎可以暂时使用,但并不是理想的方式,因为不幸的是,我无法基于浏览器的命令行条目获得可变参数我要测试。 我必须手动更新conftest文件,以获取是否运行一个或2个浏览器并对每个测试进行迭代的机会。

# conftest.py

import pytest
import os
import rootdir_ref
import webdriverwrapper
from webdriverwrapper import DesiredCapabilities, FirefoxProfile


# when running tests from command line we should be able to pass --url=www..... for a different website, check what order these definitions need to be in
def pytest_addoption(parser):
    parser.addoption('--url', action='store', default='https://mytestdomain.com.au/', help='target machine url')
    parser.addoption('--runenv', action='store', default='remote', help='select remote or local')


@pytest.fixture(scope='session')
def url(request):
    return request.config.getoption('url')


@pytest.fixture(scope='session')
def runenv(request):
    return request.config.getoption('runenv')

BROWSERS = {
    # 'firefox': DesiredCapabilities.FIREFOX,
    'chrome': DesiredCapabilities.CHROME
}

@pytest.fixture(scope='function', params=BROWSERS.keys())
def browser(request, runenv):
    if request.param == 'firefox':

        if runenv == 'local':
            firefox_capabilities = BROWSERS[request.param]
            firefox_capabilities['marionette'] = True
            firefox_capabilities['acceptInsecureCerts'] = True
            theRootDir = os.path.dirname(rootdir_ref.__file__)
            ffProfilePath = os.path.join(theRootDir, 'DriversAndTools', 'FirefoxSeleniumProfile')
            geckoDriverPath = os.path.join(theRootDir, 'DriversAndTools', 'geckodriver.exe')
            profile = FirefoxProfile(profile_directory=ffProfilePath)
            #  Testing with local Firefox Beta 56
            binary = 'C:\\Program Files\\Mozilla Firefox\\firefox.exe'
            b = webdriverwrapper.Firefox(firefox_binary=binary, firefox_profile=profile, capabilities=firefox_capabilities,
                                         executable_path=geckoDriverPath)
        elif runenv == 'remote':
            request.param == 'firefox_remote'
            firefox_capabilities = BROWSERS[request.param]
            firefox_capabilities['marionette'] = True
            firefox_capabilities['acceptInsecureCerts'] = True
            firefox_capabilities['browserName'] = 'firefox'
            firefox_capabilities['javascriptEnabled'] = True
            theRootDir = os.path.dirname(rootdir_ref.__file__)
            ffProfilePath = os.path.join(theRootDir, 'DriversAndTools', 'FirefoxSeleniumProfile')
            profile = FirefoxProfile(profile_directory=ffProfilePath)
            b = webdriverwrapper.Remote(command_executor='https://selenium.mytestserver.com.au/wd/hub',
                                        desired_capabilities=firefox_capabilities, browser_profile=profile)
        else:
            b = webdriverwrapper.Firefox()
    elif request.param == 'chrome':
        if runenv == 'local':
            desired_cap = BROWSERS[request.param]
            desired_cap['chromeOptions'] = {}
            desired_cap['chromeOptions']['args'] = ['--disable-plugins', '--disable-extensions']
            desired_cap['browserName'] = 'chrome'
            desired_cap['javascriptEnabled'] = True
            theRootDir = os.path.dirname(rootdir_ref.__file__)
            chromeDriverPath = os.path.join(theRootDir, 'DriversAndTools', 'chromedriver.exe')
            b = webdriverwrapper.Chrome(chromeDriverPath, desired_capabilities=desired_cap)
        elif runenv == 'remote':
            desired_cap = BROWSERS[request.param]
            desired_cap['chromeOptions'] = {}
            desired_cap['chromeOptions']['args'] = ['--disable-plugins', '--disable-extensions']
            desired_cap['browserName'] = 'chrome'
            desired_cap['javascriptEnabled'] = True
            b = webdriverwrapper.Remote(command_executor='https://selenium.mytestserver.com.au/wd/hub',
                                        desired_capabilities=desired_cap)
        else:
            b = webdriverwrapper.Chrome()
    else:
        b = webdriverwrapper.Chrome()
    request.addfinalizer(lambda *args: b.quit())

    return b


@pytest.fixture(scope='function')
def driver(browser, url):
    driver = browser
    driver.set_window_size(1260, 1080)
    driver.get(url)
    return driver

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM