多个相同classname的控件中查找子控件(父控件text、resource-id为空,classname不是唯一...)

本文介绍了一种在Appium自动化测试中寻找特定元素(appium)的两种方法。一种是通过遍历所有符合条件的父控件来查找目标元素,另一种则是通过定位到父控件列表中的特定位置来直接获取。此外,还讨论了这些方法的实际应用效果及局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试目的:搜索结果中找到联系人名为appium的名片,点击打开详情。

调试时发现,如果直接在当前页面使用self.driver.find_element_by_name("appium"),查找失败。

此时考虑使用父控件查找子控件。
接下来,
一、首先要找到父控件了。。。
然而搜索结果有多个,并且通过uiautomator看到 ,父控件text、resource-id为空,classname不是唯一的,且classname同为android.view.View的控件不止4个,比如下面的截图中classname同为android.view.View的控件,除了搜索结果同类的有4个外,其他的还有3个,一共有7个。

解决方法1:使用python list存放classname同为android.view.View的控件,遍历list,从父控件中查找子控件,如果子控件的name为appium,则为结果。

name_list= self.driver.find_elements_by_class_name("android.view.View")

for i in name_list:
    try:
        if i.find_element_by_name("appium"):
        name_appium=i.find_element_by_name("appium")
    except Exception,e:
        print e
name_appium.click()


解决方法2:
另外,通过调试发现
name_list= self.driver.find_elements_by_class_name("android.view.View")
第一个搜索结果,appium所在的父控件,对应的是name_list中的name_list[3]
              
最后一个搜索结果,(上图中的联系人名为appiumtest所在的父控件),对应的是name_list中的name_list[len(name_list)-1],依据经验,从下往上数,那么第一个搜索结果appium所在的父控件,对应的是name_list[len(name_list)-4],调试后发现确实如此。

这种查找并写死的方法虽然可用于当前页面,实际操作以来效率比较低,并且兼容性不好,比如换了不同的界面有更多相同classname的控件,可能不会是list[3]了;如果搜索结果有5个,那么第一个搜索结果应该是list[len(list)-5]了,需要统计搜索结果的个数,并进一步调试。。。
二、父控件查找子控件,并操作控件
解决方法一中,上面的代码中,已经实现了:
name_appium=i.find_element_by_name("appium")
name_appium.click()

三、小结
遇到上面的情况也算特殊了,如果是在实际项目中,resource-id都加上会更方便,另外也想过使用坐标的方法点击,应该是要根据屏幕比例确定坐标,不然换了不同分辨率的手机,估计要报错了。


### 使用 uiautomator2 查找特定控件的方法及代码示例 uiautomator2 是一种强大的工具,用于在 Android 设备上自动化测试和操作 UI 控件。通过该工具,可以查找特定的 UI 元素,并执行各种操作。以下是一个使用 uiautomator2 查找所有符合特定条件的小部件的代码示例[^3]。 ```python import uiautomator2 as u2 # 连接到设备 d = u2.connect() # 查找所有 className 为 'android.widget.TextView' 的小部件 text_views = d(className="android.widget.TextView").all() for idx, tv in enumerate(text_views): print(f"TextView {idx}: text='{tv.get_text()}', bounds={tv.info['bounds']}") # 查找所有包含特定文本的小部件 specific_widgets = d(textContains="Clock").all() for widget in specific_widgets: print(f"Found widget with text: {widget.get_text()}, class: {widget.info['className']}") ``` 上述代码首先连接到 Android 设备,然后通过 `className` 或 `textContains` 条件查找所有符合条件的小部件,并打印其文本内容和边界信息。 如果需要更复杂的条件匹配,例如查找某个父节点下的节点,可以参考以下代码: ```python # 查找 className 为 'android.widget.ListView' 的控件,并在其节点中查找包含 "Bluetooth" 的元素 bluetooth_items = d( className="android.widget.ListView", resourceId="android:id/list" ).child_by_text("Bluetooth", allow_scroll_search=True, className="android.widget.LinearLayout").all() for item in bluetooth_items: print(f"Bluetooth item found: {item.get_text()}") ``` 此代码片段展示了如何结合 `child_by_text` 方法以及滚动搜索功能来查找特定的元素[^2]。 --- ### 注意事项 1. **安装 uiautomator2** 在使用 uiautomator2 前,需确保已正确安装该库。由于它仍处于开发阶段,建议使用 `--pre` 参数安装最新版本: ```bash pip install --pre uiautomator2 ``` 2. **设备连接** 确保设备已通过 USB 或 Wi-Fi 正确连接,并启用了开发者模式和 USB 调试功能。 3. **权限问题** 某些操作可能需要额外的权限。可以通过以下命令授予必要权限: ```bash adb shell pm grant <package_name> android.permission.<permission_name> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值