51Testing软件测试论坛
标题:
一个新版本引发一个问题之Appium
[打印本页]
作者:
韶光暗淡
时间:
2023-7-21 10:13
标题:
一个新版本引发一个问题之Appium
本帖最后由 韶光暗淡 于 2023-7-21 10:19 编辑
准备工作
1、测试代码
<font size="3">from appium import webdriver
des_cap = {'platformName': 'android'}
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
desired_capabilities=des_cap)</font>
复制代码
2、测试环境
python 3.10,虚拟环境
pycharm 2018 community
测试时间 2023-7-20
3、场景一:默认安装PASS
在pycharm中安装appium-python-client,版本不指定,此时是2.11.1
对应依赖selenium4.10.0
执行示例代码
测试通过
??? 所以博主你要表达啥
继续看下去
4 场景二:appium-python-client2.6.0+selenium4.10 FAlL
你根据指定版本安装appium-python-client为2.6,自动安装selenium4.10
执行示例代码
测试失败
提示如下
<font size="3">D:\Appium01\venv\Scripts\python.exe D:/Appium01/demo1.py
Traceback (most recent call last):
File "D:\Appium01\demo1.py", line 9, in <module>
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
File "D:\Appium01\venv\lib\site-packages\appium\webdriver\webdriver.py", line 230, in __init__
super().__init__(
TypeError: WebDriver.__init__() got an unexpected keyword argument 'desired_capabilities'</font>
复制代码
五 场景3:appium-python-client2.6.0+selenium4.3.0 PASS
你应该是先安装selenium4.3.0
然后再安装appium-python-client2.6.0
都是指定版本安装
有同学会说,谁会这样安装呢
会的,因为你可能是先学selenium(我课程要求是4.3,最新的版本4.10的改进对我们没有太大意义,但底层确实改变了很多)
测试通过
6、问题说明
TypeError 分析
先看报错
<font size="3">TypeError: WebDriver.__init__() got an unexpected keyword argument 'desired_capabilities'</font>
复制代码
主要版本信息:
appium-python-client2.6.0
selenium4.10
报错行
<font size="3">driver = webdriver.Remote</font>
复制代码
Remote是个别名
<font size="3"> from .webdriver import WebDriver as Remote</font>
复制代码
看WebDriver源码
<font size="3">class WebDriver(
webdriver.Remote,
ActionHelpers,
Activities,
Applications,
Clipboard,
Context,
Common,
DeviceTime,
Display,
ExecuteDriver,
ExecuteMobileCommand,
Gsm,
HardwareActions,
ImagesComparison,
IME,
Keyboard,
Location,
LogEvent,
Network,
Performance,
Power,
RemoteFS,
ScreenRecord,
Session,
Settings,
Sms,
SystemBars,
):
def __init__(
self,
command_executor: str = 'http://127.0.0.1:4444/wd/hub',
desired_capabilities: Optional[Dict] = None,
browser_profile: str = None,
proxy: str = None,
keep_alive: bool = True,
direct_connection: bool = True,
extensions: Optional[List['WebDriver']] = None,
strict_ssl: bool = True,
options: Union[AppiumOptions, List[AppiumOptions]] = None,
):</font>
复制代码
__init__中传递了desired_capabilities没有问题
继续分析堆栈
<font size="3">File "D:\Appium01\venv\lib\site-packages\appium\webdriver\webdriver.py", line 230, in __init__
super().__init__(</font>
复制代码
继续看WebDriver此处源码
<font size="3">File "D:\Appium01\venv\lib\site-packages\appium\webdriver\webdriver.py", line 230, in __init__
super().__init__(</font>
复制代码
继续看WebDriver此处源码
<font size="3"> super().__init__(
command_executor=AppiumConnection(command_executor, keep_alive=keep_alive),
desired_capabilities=desired_capabilities,
browser_profile=browser_profile,
proxy=proxy,
options=options,
)</font>
复制代码
这里也有desired_capabilities,为何报错了呢
请看WebDriver的继承webdriver.Remote
<font size="3">class WebDriver(BaseWebDriver):
_web_element_cls = WebElement
_shadowroot_cls = ShadowRoot
def __init__(
self,
command_executor="http://127.0.0.1:4444",
keep_alive=True,
file_detector=None,
options: Union[BaseOptions, List[BaseOptions]] = None,
) -> None:</font>
复制代码
到这里你发现了,这个__init__里面没有desired_capabilities
注意webdriver.Remote是隶属于selenium的,你此时的selenium是4.10,升级了,可能导致它remove了一些参数
作者:
韶光暗淡
时间:
2023-7-21 10:17
6.2appium-python-client2.11.1+selenium4.10
这是默认组合,要知道selenium也是4.10了,为何没有报错呢?
其调用关系简单分析下
在Remote的__init__中,也支持desired_capabilities,但有如下信息
<font size="3"> # TODO: Remove the deprecated arg
desired_capabilities: Optional[Dict] = None,
if desired_capabilities is not None:
warnings.warn(
'desired_capabilities argument is deprecated and will be removed in future versions. '
'Use options instead.',
DeprecationWarning,
)</font>
复制代码
后续要移除desired_capabilities
用options替代(模仿selenium)
关键的问题是在于,appium-python-client2.11.1中对父类__init__的调用是不携带desired_capabilities的
<font size="3"> super().__init__(
command_executor=command_executor,
options=dst_options,
)</font>
复制代码
[backcolor=rgba(255, 255, 255, 0.9)]
完整代码片段如下
<font size="3">class WebDriver(
webdriver.Remote,
ActionHelpers,
Activities,
Applications,
Clipboard,
Context,
Common,
DeviceTime,
Display,
ExecuteDriver,
ExecuteMobileCommand,
Gsm,
HardwareActions,
ImagesComparison,
IME,
Keyboard,
Location,
LogEvent,
Network,
Performance,
Power,
RemoteFS,
ScreenRecord,
Session,
Settings,
Sms,
SystemBars,
):
def __init__(
self,
command_executor: Union[str, AppiumConnection] = 'http://127.0.0.1:4444/wd/hub',
# TODO: Remove the deprecated arg
desired_capabilities: Optional[Dict] = None,
# TODO: Remove the deprecated arg
browser_profile: Union[str, None] = None,
# TODO: Remove the deprecated arg
proxy: Union[str, None] = None,
keep_alive: bool = True,
direct_connection: bool = True,
extensions: Optional[List['WebDriver']] = None,
strict_ssl: bool = True,
options: Union[AppiumOptions, List[AppiumOptions], None] = None,
):
if strict_ssl is False:
# pylint: disable=E1101
# noinspection PyPackageRequirements
import urllib3
# pylint: disable=E1101
# noinspection PyPackageRequirements
import urllib3.exceptions
# noinspection PyUnresolvedReferences
AppiumConnection.set_certificate_bundle_path(None)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
if isinstance(command_executor, str):
command_executor = AppiumConnection(command_executor, keep_alive=keep_alive)
if browser_profile is not None:
warnings.warn('browser_profile argument is deprecated and has no effect', DeprecationWarning)
if proxy is not None:
warnings.warn('proxy argument is deprecated and has no effect', DeprecationWarning)
if desired_capabilities is not None:
warnings.warn(
'desired_capabilities argument is deprecated and will be removed in future versions. '
'Use options instead.',
DeprecationWarning,
)
# TODO: Remove the fallback after desired_capabilities removal
dst_options = (
AppiumOptions().load_capabilities(desired_capabilities)
if desired_capabilities is not None and options is None
else options
)
super().__init__(
command_executor=command_executor,
options=dst_options,
)</font>
复制代码
6.3appium-python-client2.6.0+selenium4.3.0
想必分析到此处,你应该盲猜能知道为何这个也PASS了
是因为selenium的版本中webdriver.Remote中是有desired_capabilities的
<font size="3">class WebDriver(BaseWebDriver):
_web_element_cls = WebElement
_shadowroot_cls = ShadowRoot
def __init__(self, command_executor='http://127.0.0.1:4444',
desired_capabilities=None, browser_profile=None, proxy=None,
keep_alive=True, file_detector=None, options: Union[BaseOptions, List[BaseOptions]] = None):</font>
复制代码
7.0总结:
最新版本appium-python-client即将不提供desired_capabilities的传参,但目前能用
在selenium4.10中已经不支持desired_capabilities参数
错误的搭配可能会引发上述问题,要么用最新的版本(默认安装),要么2个都用较低的版本
留在最后的问题,那么在appium最新版中应该如何传递能力值呢?
<font size="3">from appium import webdriver
from appium.options.common import AppiumOptions
option = AppiumOptions()
option.set_capability('platformName','android')
driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
options=option)</font>
复制代码
欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/)
Powered by Discuz! X3.2