【问题标题】:Python: command line argument not passing the same way as hard coded linesPython:命令行参数的传递方式与硬编码行不同
【发布时间】:2015-02-24 03:13:56
【问题描述】:

我正在编写一些 Selenium 脚本来测试跨不同设备、浏览器和平台的站点。除了定义命令执行器 URL 和浏览器功能的两行之外,我可以使用相同的代码使脚本工作。 我正在尝试构建一个脚本,我可以在其中使用命令行参数定义这些行。

这是我的代码:

from selenium import webdriver
import time
import sys
import getopt
def main(argv):
    #define desired browser capabilities
    desktopCapabilities = {'browserName': 'chrome'} #change browserName to: 'firefox' 'chrome' 'safari' 'internet explorer'
    iosCapabilities = {'platformName': 'iOS' ,'platformVersion': '8.1' ,'deviceName': 'iPad Air','browserName': 'Safari'}
    androidCapabilities = {'chromeOptions': {'androidPackage': 'com.android.chrome'}}
    # Establish the command executor URL
    desktopExecutor = 'http://127.0.0.1:4444/wd/hub'
    iosExecutor = 'http://127.0.0.1:4723/wd/hub'
    androidExecutor = 'http://127.0.0.1:9515'

    cmdExecutor = desktopExecutor
    browserCapabilities = desktopCapabilities
    try:
      opts, args = getopt.getopt(argv,"he:c:",["executor=","capabilities="])
    except getopt.GetoptError:
      print 'test.py -e <executor> -c <capabilities>'
      sys.exit(2)
    for opt, arg in opts:
      if opt == '-h':
         print 'test.py -e <executor> -c <capabilities>'
         sys.exit()
      elif opt in ("-e", "--executor"):
         cmdExecutor = arg
      elif opt in ("-c", "--capabilities"):
         browserCapabilities = arg

    print 'Command executor is:', cmdExecutor
    print 'Desired capabilities are:', browserCapabilities
    driver = webdriver.Remote(command_executor=cmdExecutor, desired_capabilities=browserCapabilities)
    driver.get("http://google.com")
    time.sleep(5)
    driver.quit()
if __name__ == "__main__":
   main(sys.argv[1:])

如果我不通过命令行添加任何参数,此代码将按预期运行。如果我运行它也可以:

python test.py -e 'http://127.0.0.1:4444/wd/hub'

如果我使用以下命令运行它会中断,因为 -c 没有作为字典传递:

python test.py -e 'http://127.0.0.1:4444/wd/hub' -c {'browserName': 'firefox'}

我怎样才能让它运行:

python test.py -e iosExecutor -c iosCapabilities

这是我运行上述命令时得到的输出:

 python my_script.py -e iosExecutor --capabilities iosCapabilities
Command executor is: iosExecutor
Desired capabilities are: iosCapabilities
Traceback (most recent call last):
  File "my_script.py", line 38, in <module>
    main(sys.argv[1:])
  File "my_script.py", line 33, in main
    driver = webdriver.Remote(command_executor=cmdExecutor, desired_capabilities=browserCapabilities)
  File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 62, in __init__
    raise WebDriverException("Desired Capabilities must be a dictionary")
selenium.common.exceptions.WebDriverException: Message: Desired Capabilities must be a dictionary

基本上它就像我这样通过第 33 行一样运行:

driver = webdriver.Remote(command_executor="iosExecutor", desired_capabilities="iosCapabilities")

如果我使用“iosExecutor”和“iosCapabilites”对第 15 行和第 16 行进行硬编码,它也可以工作,所以这告诉我这是我从 CLI 传递信息的方式。

任何建议都会很棒。我对这个(编程)很陌生,所以我猜可能有更好的方法来做到这一点,但谷歌并没有为我解决这个问题。

【问题讨论】:

  • 为什么不将-c 添加为字符串参数,例如“ios”、“android”或“desktop”,并以编程方式选择其中一个功能参数?我的意思是如果给定的命令行参数等于“android”设置 browserCapabilities=androidCapabilities

标签: python selenium selenium-webdriver command-line-arguments


【解决方案1】:

使用argparse 会让事情变得更容易。对于capabilities,您可以使用json.loadsast.literal_eval 作为type,例如,在此处完成:

对于executor,要么将url作为字符串传入,要么定义一个用户友好的映射,比如:

EXECUTORS = {
    'desktop': 'http://127.0.0.1:4444/wd/hub',
    'ios': 'http://127.0.0.1:4723/wd/hub',
    'android': 'http://127.0.0.1:9515'
}

下面是代码最终的样子:

import ast
import time
import argparse

from selenium import webdriver


EXECUTORS = {
    'desktop': 'http://127.0.0.1:4444/wd/hub',
    'ios': 'http://127.0.0.1:4723/wd/hub',
    'android': 'http://127.0.0.1:9515'
}

parser = argparse.ArgumentParser(description='My program.')
parser.add_argument('-c', '--capabilities', type=ast.literal_eval)
parser.add_argument('-e', '--executor', type=str, choices=EXECUTORS)

args = parser.parse_args()

driver = webdriver.Remote(command_executor=EXECUTORS[args.executor], desired_capabilities=args.capabilities)
driver.get("http://google.com")
time.sleep(5)
driver.quit()

示例脚本运行:

$ python test.py -e android -c "{'chromeOptions': {'androidPackage': 'com.android.chrome'}}"
$ python test.py -e ios -c "{'platformName': 'iOS' ,'platformVersion': '8.1' ,'deviceName': 'iPad Air','browserName': 'Safari'}" 
$ python test.py -e desktop -c "{'browserName': 'chrome'}"

而且,作为奖励,您会获得由argparse 神奇制作的内置帮助:

$ python test.py --help
usage: test.py [-h] [-c CAPABILITIES] [-e {android,ios,desktop}]

My program.

optional arguments:
  -h, --help            show this help message and exit
  -c CAPABILITIES, --capabilities CAPABILITIES
  -e {android,ios,desktop}, --executor {android,ios,desktop}

【讨论】:

  • 这是一个很好的答案。它解决了我的问题,并为我想做的事情提供了更好的方法。谢谢!
猜你喜欢
  • 2016-03-25
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 2013-12-10
  • 2013-12-16
  • 1970-01-01
相关资源
最近更新 更多