Appium Appium python client 网络连接相关 api 用法

陈恒捷 · 2015年10月08日 · 最后由 黄晓阳 回复于 2018年05月16日 · 3367 次阅读

前言

今天有人问到我这个问题,并且尝试过传入数字/字符串作为参数均不成功。于是看了下,发现要找到正确用法需要对 client 源码有一定了解,并且 google 和 github 上都没有找到对应的使用示例,所以在这里记录一下。

问题描述

appium 一直有一个设置和获取当前各项连接状态的 api ,官方文档中可用参数及使用方法如下:

Value (Alias) Data Wifi Airplane Mode
0 (None) 0 0 0
1 (Airplane Mode) 0 0 1
2 (Wifi only) 0 1 0
4 (Data only) 1 0 0
6 (All network on) 1 1 0
// javascript
// set airplane mode
driver.setNetworkConnection(1)

// set wifi only
driver.setNetworkConnection(2)

// set data only
driver.setNetworkConnection(4)

// set wifi and data
driver.setNetworkConnection(6)

但在 python client 中使用这样的代码会报错:

self.driver.set_network_connection(1)

报错信息:

Error
Traceback (most recent call last):
  File "/Users/NextGen/Documents/Framework/test.py", line 35, in test_search
    self.driver.set_network_connection(1)
  File "/Library/Python/2.7/site-packages/appium/webdriver/webdriver.py", line 623, in set_network_connection
    'type': connectionType.value
AttributeError: 'int' object has no attribute 'value'

解决过程

参考资料:8.13. enum — Support for enumerations

首先,出现 AttributeError 这个很奇怪,这里传入的东西为啥会有 value 这个属性?难道传的不是基本数据类型,而是一个对象?于是看了下这个方法的源码:

def set_network_connection(self, connectionType):
    """Sets the network connection type. Android only.
    Possible values:
        Value (Alias)      | Data | Wifi | Airplane Mode
        -------------------------------------------------
        0 (None)           | 0    | 0    | 0
        1 (Airplane Mode)  | 0    | 0    | 1
        2 (Wifi only)      | 0    | 1    | 0
        4 (Data only)      | 1    | 0    | 0
        6 (All network on) | 1    | 1    | 0
    These are available through the enumeration `appium.webdriver.ConnectionType`

    :Args:
     - connectionType - a member of the enum appium.webdriver.ConnectionType
    """
    data = {
        'parameters': {
            'type': connectionType.value
        }
    }
    return self.execute(Command.SET_NETWORK_CONNECTION, data)['value']

关键字:

- connectionType - a member of the enum appium.webdriver.ConnectionType

翻译一下这个注释:

- connectionType - 枚举类型 appium.webdriver.ConnectionType 中的成员

然后看看 appium.webdriver.ConnectionType

...
class ConnectionType(Enum):
    NO_CONNECTION = 0
    AIRPLANE_MODE = 1
    WIFI_ONLY = 2
    DATA_ONLY = 4
    ALL_NETWORK_ON = 6

ok,明白了。就是 connectionType 必须是 appium.webdriver.ConnectionType 里的其中一个成员。接下来就简单了。

问题解决

正确的使用方法:

# python
# set network  
from appium.webdriver.connectiontype import ConnectionType
self.driver.set_network_connection(ConnectionType.AIRPLANE_MODE)

# get network
self.driver.network_connection # it would return int type, like 0, 1, 2, 4, 6
ConnectionType(self.driver.network_connection).name # it would return mode name, like AIRPLANE_MODE, WIFI_ONLY

总结

这个其实本来没什么问题的,只是官方文档缺失导致用的时候要稍微探究一下才会用。同时也简单学习了一下怎么在 python 中使用枚举。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 28 条回复 时间 点赞

恒洁姐姐牛 B

所以就是 Python 的 set_network_connection(self, connectionType) 函数的参数不是数字而是 enum 对象;而 JS 的 setNetworkConnection(arg) 函数参数直接就是数字

#3 楼 @watman 对的。其他语言的 client 没试过,不知道用哪种方式。

如此研究深度, 国内少见啊. 恒捷进步好快.

谢谢 hengjie 解决了我的问题,大赞

#5 楼 @seveniruby 哈哈,谢谢。其实也不深啦,我要学习的东西还有很多。

都能分析源码,小白新手只能仰望!

#9 楼 @tagore_shao 我觉得最有成就感的是不仅发现了 bug ,而且还找到了修复的方法。我相信开发也更愿意和这样的测试合作。
大家一起加油啊!

官方文档在哪能看到??一直在找,在 github 上找的好像不全

你好,我是按照上面的步骤来的,in python,连接的 iOS 模拟器 8.4
from appium.webdriver.connectiontype import ConnectionType
self.driver.set_network_connection(ConnectionType.AIRPLANE_MODE)
但是第 2 行 set network 的时候报错😭
ValueError: No JSON object could be decoded
为什么会酱紫。。😭 ,已经看了老半天了,求大神们拯救@chenhengjie123

#11 楼 @huanzhijin client 端的要看 webdriver 和 appium client 两者的文档(在对应 github 项目里),appium client 本身只会写它自己添加了的内容
server 端统一都在 appium 的 github 里

#12 楼 @yesi 附上你的 server log 和完整一些的测试代码看看?

#14 楼 @chenhengjie123 Sorry,刚才我在隔壁一篇文章快末尾的地方看到, “中文 Appium API 文档 by xiaoli” - https://testerhome.com/topics/3144,“很不幸,目前 Appium 在 iOS 下不支持 Selenium 的网络连接 API。”,说是网络设置这块不支持 iOS,只支持 Android。。我的是 iOS 模拟器,等会再去试试 Android 哈。谢谢

#15 楼 @yesi 是的,iOS 上无论是模拟器还是真机都不支持设置网络连接。

#5 楼 @seveniruby hi,大神,问你个小白问题,appium 命令行安装后,是否不能开启 appium inspector,必须得界面安装 appium 才行呢?

#17 楼 @turinblueice 对的,inspector 是 GUI 程序自带的,命令行的 appium 没有 inspector 工具。

#18 楼 @chenhengjie123 所以说,如果要去扫描 app 控件的 id,获取这些元素的字段信息(ID、name、xpath 等),还得必须图形化安装 appium 啊?

#19 楼 @turinblueice 如果是 android ,用 uiautomatorviewer 就好。iOS 还是用 inspector 吧。

ConnectionType(self.driver.network_connection).NO_CONNECTION,报错原因:TypeError: object() takes no parameters,大神求决解办法

#21 楼 @overfly_zzl 我和你一样,不知道为什么报这个错,可能是数据类型不一致吧。鉴于是要获取当前网络状态的目的,自己写了个字典,用

self.driver.network_connection

获取当前的网络状态 int 值,再根据 ConnectionType 类写个字典,用返回的值读取字典内容。如下:

info = {"0":"NO_CONNECTION",
        "1":"AIRPLANE_MODE",
        "2":"WIFI_ONLY",
        "4":"DATA_ONLY",
        "6":"ALL_NETWORK_ON"}

stat = self.driver.network_connection
s = "%s"%stat
status = info.get(s)
print(status)

抛砖引玉,希望有更好的解决办法。

太棒了,帮我大忙了😭

#22 楼 @t880216t 看了下,appium python client 源码改了,现在 ConnectionType 直接继承的是 object ,不是 Enum ,所以以前的用法用不了。

可以参考下面的用法根据 self.driver.network_connection 的值获取 ConnectionType 的对应属性名:

# python
from appium.webdriver.connectiontype import ConnectionType

def get_connection_name(connection):
    """
    根据 connection 的值获取对应状态名
    :param connection: 通过 driver.network_connection 获取到的网络状态
    :return: 对应状态名,如 NO_CONNECTION
    """
    for attr in ConnectionType.__dict__:
        if ConnectionType().__getattribute__(attr) == connection:
            return attr
    raise AttributeError("ConnectionType with value %s do not exist." % connection)

# 获取状态名
get_connection_name(self.driver.network_connection)
Brian [该话题已被删除] 中提及了此贴 11月03日 16:56

@chenhengjie123,self.driver.set_network_connection(ConnectionType.WIFI_ONLY),报错 Stderr: 'java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.AIRPLANE_MODE from pid=27616, uid=2000,是不是手机需要 root 才行的啊

cheng 回复

不用 root ,你检查下安装 apk 时,是不是有些权限没有赋予?

28楼 已删除

实测表明,手机上的飞行模式是的打开了,当前状态也是 1,可是 wifi 和蓝牙并没有被关闭,虽然手机上显示的是飞行模式打开了,可是手动点击飞行模式 wifi 和蓝牙就可以关闭,不理解为何会这样

cheng 回复

hi,我现在也遇到这个问题,但是找不到原因,这是为什么?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册