[英]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
在这里,为什么要使用url
和runenv
作为灯具? 您可以如下使用它:
在你的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')
现在,无论您要访问url
和runenv
哪里, 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.