软件测试 | 高级定位技巧

518 篇文章 3 订阅
514 篇文章 2 订阅
本文详细介绍了在App自动化测试中,如何使用XPath的高级定位技巧,包括模糊匹配、组合定位和层级定位,以及如何通过UiAutomator进行高效定位。此外,还提到了Appium新增的CSS选择器支持,作为UiSelector的替代方式。这些技术有助于提高测试脚本的稳定性和准确性。
摘要由CSDN通过智能技术生成

通常使用定位工具定位App页面上的元素会发生定位不到元素或者定位元素失败的情况。发生这种情况可能是App的页面不唯一,也可能是App的页面发生了变化。下面介绍定位元素的高级用法,使用层级关系定位或者多重属性定位的方式来确定了App页面元素的唯一性,从而更精准、更稳定地定位到我们想要App页面元素。

1.XPath高级定位技巧

(1)XPath简介

XPath的英文全称为XML Path Language,意为对XML中的元素进行路径定位的一种语言,它使用与XML标记语言、HTML标记语言,App Dom结构。XPath是我们做自动化测试中进行元素定位时用的比较多的工具,它可使用与Seleniu、Appium和Appcrawler。前面章节已经对XPath进行了一些说明,下面只对XPath做举例说明。

(2)XPath基本语法

表5-4是XPath的常用方法。

 

(3)XPath模糊定位技巧

XPath中的contains()是模糊匹配的定位方法,若在定位元素时,一个元素的属性不固定,这时就可以用模糊匹配来定位元素。使用格式为//[contains(@content-desc,'帮助')],示例代码如下(Python版和Java版)。

Python版

driver.find_element(By.XPATH,
'//*[contains(@text,"测试")]')
​
driver.find_element(By.XPATH,
'//*[contains(@content-desc,"搜索")]')
​
driver.find_element(By.XPATH,
'//*[contains(@resource-id,"login_phone")]')

Java版本

driver.findElement (By.xpath(
       "//*[contains(@text,\"测试")]"));
      
driver.findElement(By.xpath(
        "//*[contains(@content-desc,\"搜索"\)]"));
        
driver.findElement(By.xpath(
         "//*[contains(@resource-id,\"login_phone\")]"));

(4)XPath组合定位技巧

用XPath可以同时匹配两个甚至多个属性来完成元素定位。这里常用的属性有text、resource-id、class、index、content-desc等,任意组合这些属性完成定位,示例代码如下(Python版和Java版)。

Python版本

driver.find_element(
    By.XPATH,'//*[@text="我的" and @resource-id="tab_name"]'
    ).click()
    
driver.find_element(
    By.XPATH,'//*[@text="注册/登录" and @index="1"]
    ').click()

Java版本

driver.findElemnt(By.xpath(
     "//*[@text=\"我的\ and @resource-id=\"tab_name\"]")).click();
     
driver.findElement(By.xpath(
      "//*[@text=\"注册/登录\" and @index=\"1"]")).click();

(5)XPath层级定位

我们定位元素的时候可能会设计通过子元素去定位父元素,或者用父元素定位子元素,或者定位兄弟元素,XPath支持父子关系、兄弟关系元素的查找与定位。示例代码如下(python版和Java版)。

Python版本

# 通过子元素定位父元素
# 方法一: ..
driver.find_element_by_xpath(
   '//*[@text="手机号"]//..').tag.name
   
# 方法二:parent::*
driver.find_element_by_xpath(
    '[@text="手机号"]/parent::*').tag.name
    
#通过某元素定位其兄弟元素
driver.find_element_by_xpath(
    '//*[text="手机号"]/../li'
    ).tag_name

Java版本

//通过子元素定位父元素
//方法一:..
driver.findElement(By.xpath(
  "//*[@text=\"手机号\"]/..")).getTagName();
  
//方法二 parent::*
driver.findElement(By.xpath(
   "[@text=\"手机号\"]/parent::*")).getTagName();
   
//通过某元素定位其兄弟元素
driver.find_Element(By.xpath(
    "//*[@text=\"手机号\"]/../li"
    )).getTagName();

2.实例案例

(1)场景一

App应用:雪球apk。

我们首先使用UI Automator Viewer工具对该App进行DOM分析,然后使用XPath对分析到的元素进行定位,如图5-14所示的搜索框,我们可以使用元素的多种元素对搜索框进行定位,常用的属性有text、resource-id、class和content-desc等。

这里推荐使用resource-id进行定位,通常情况下,它是App页面元素的卫衣属性,用XPath编程实现定位的代码如下(Python版和Java版)。

Python演示代码

driver.find_element(
    By.XPATH,'//*[contains(@resource-id,"tv_search")]')
 # 或者也可以写成下面这样
 driver.find_element(By.ID,'tv_search')

 Java演示代码

driver.findElement(By.xpath("//*[contains(@resource-id,
        \"tv_search\")]"));
//或者也可以写成下面这样
driver.findElement(By.id("tv_search"));

(2)场景二

如图5-15所示,获取 “ BABA”所对应的股票价格 “187.11”,可以使用XPath父关系来进行元素定位。

 定位实现的代码如下(Python版和Java版)

Python演示代码

curr_price = self.driver.find_element(
   MobileBy.XPath,"//*[@text='BABA']/../../..\
   //*[@resource-id='com.xueqiu.android:id/current_price']")

Java演示代码

MobileElement curr_price = driver.findElement(
      By.xpath("//*[@text=\"BABA\"]/../../..//\
      *[@redource-id='com.xueqiu.android:id/current_price']"));

3.UIAutomator定位技巧

UiAutomator是Android SDK自带的一个测试框架,这个测试框架提供了一些列的API,用这些API可以与用Android开发的APP进行交互,例如,打开菜单、点击、滑动等。当Appium的Caps参数uiautomatorName设置为UiAutomator2时,就能够实现计算机端与手机端的UiAutomator通信,并且我们可以使用UiAutomator执行测试代码。UiAutomator1是比较旧的版本,如果想测试较旧版本的基于Android系统开发的App(低于Android 4.4版本),需要设置Appium的Caps参数:uiautomationName="UiAutomator1"。

由于UiAutomator是Android SDK自带的 “工作引擎”,使用这个测试框架进行元素定位,执行速度要比用XPath定位元素快很多。但由于UiAutomator的用法比较特殊,调试起来相对麻烦,如果测试脚本中的定位语句编写不当,脚本编辑器也不会给出任何错误提示信息,只能在运行的时候检验测试脚本的对错。

下面就单独介绍一下基于UiAutomator定位元素的方法,基本语法如下(Python版和Java版)。

Python版本

driver.find_elemnet_by_android_uiautomator()

Java版本

driver.findElement(MobileBy.AndroidUIAutmator());

常用的UiAutomator方法如下:

UiSelenium()   #实现元素定位
UiScrollable() #实现滚动查找元素

(1)通过text定位

UiSelector()的用法与XPath类似,可以通过元素的text属性来定位元素。Uiselector的语法格式如下:

new UiSelector().text("text文本")

UiSelector也适用模糊查询的方式来定位元素。

UiSelector的演示代码如下(Python版和Java版)。

Python版本

driver.find_element_by_android_uiautomator(
    'new UiSelector().textContains("手机")').click()

Java版本

driver.findElementByAndroidUIAutomator(\
    "new UiSelector().textContains(\"手机\")").click();

(2)通过resourceId定位

UiAutomator同样也能用ID定位元素,格式为new UiSelector().resourceId("resource-id属性"),示例代码如下(Python版和Java版本)。

Python版本

driver.find_element_by_android_uiautomator(
    'new UiSelector().resourceId("rl_login_phone")').click()

Java版本

driver.findElementByAndroidUIAutomator("new UiSelector().\
resourceId(\"rl_login_phone\")").click();

(3)通过className定位

App页面上元素的class属性一般不唯一,此时可以根据下标对元素定位,格式new UiSelector().className("className"),一般使用find_elements完成元素定位,示例代码如下(Python版和Java版)。

Python版本

driver.find_elements_by_android_uiautomator(
  'new UiSelector().\
  className("android.widget.TestView"))'[5].click()

Java版本

driver.findElementsByAndroidUIAtor("new UiSelector().\
className(\"android.widget.TestView\")")[5].click();

(4)通过description定位

description也支持content-desc定位方式,格式为new UiSelector().description("content-des"属性),示例代码如下(Python版和Java版)。

Python版本

driver.find_element_by_android_uiautomator(
  'new UiSelector().description("搜索")').click()

Java版本

driver.findElementByAndroidUIAutomator("new \
UiSelector().description(\"搜索\")").click();

(5)组合定位方式

UiAutomator也支持属性组合定位元素,示例代码如下(Python版和Java版)。

Python版本

driver.find_element_by_android_uiautomator(
 'new UiSelector().resourceId(\
 "com.xueqiu.android:id/tv_login_phone").text("手机号")').click();

Java版本

driver.findElementByAndroidUIAutomator("new UiSelector().resourceId(\
\"com.xueqiu.android:id/tv_login_phone\").text(\"手机号\")").click();

(6)滚动查找元素

UiAutomator使用 UiScrollable()方法可以滚动查找指定的某个元素,示例代码如下(Python版和Java版)。

driver.find_element_by_android_uiautomator(
  'new UiScrollable(new UiSelector().scrollable(true\
  .instance(0)).scrollIntoView(new UiSelector()\
  .text("我的").instance(0);').)click()

Java版本

driver.findElementByAndroidUIAutomator(\
  "new UIScrollable(new UiSelector().scrollable(ture)\
  .instance(0)).scrllIntoView(new UiSelector().\
  text(\"我的\").instance(0));").click();

上面的测试代码作用是,在当前的页面滚动查找text属性值是 “我的” 这个元素,找到之后执行点击操作。

4.css selector元素定位

Appium Server从1.19.0版本开始,增加了用css selector方式进行元素定位的支持,即appiumuiautomator2-driver会将css selector定位方式转化成UiAutomator定位方式。

注意:Appium Inspector中暂时没有添加这种定位当时。

由于UiSelector()的表达式用的是Java格式的语法,因此编写定位元素的表达式很复杂,且在用工具编写代码时(如Pycharm、VSCode、IntelliJ IDEA等工具),若代码编写错误也不会有任何提示信息。只能是代码运行时才能发现其中表达式的错误。css selector 的语法会自动转成UiAutomator的语法结构,这种官方提供的原生的定位元素的方式,定位速度更快一些。

(1)ID定位

css selector 可以用ID进行元素定位。飞马如下(Python版和Java版)(#igk 表示css selector 定位符)。

Python版本

driver.find_element_by_css_selector('#igt')
driver.find_element_by_id_('android:id/igk')

Java版本

driver.findElementByCssSelector("#igk").click();
driver.findElementById("android:id/igk").click();

(2)class name定位

css selector使用class name进行元素定位的代码如下(Python版和Java版)(css selector 的定位符为.android.widget.ImageView)。

Python版本

driver.find_element_by_css_selector('.android.widget.ImageView')
driver.find_element_by_class_name("android.widget.ImageView")

Java版本

driver.findElementByCssSelector(".android.widget.ImageView");
driver.findElementByClassName("android.widget.ImageView");

(3)text定位

css selector 使用text进行元素定位的代码如下(Python版和Java版)(css selector的定位符为“*[text=‘工作台’]”)。

Python版本

driver.find_element_by_css_selector("*[text='工作台']")

注:对应XPath定位器的代码时driver.find_element_by_xpath("//*[@text='工作台']")。

Java版本

driver.findElementByCssSelector("*[text=\"工作台\"]");

注:对应XPath定位器的代码是driver.findElementByXPath("//*[@text= \ "工作台"]").

(4)description定位

css selector使用description进行元素定位的代码如下(Python版和Java版)(css selector的定位符为*[description="ContentDescription"])。

Python版本

driver.find_element_by_scc_selector('*[description="ContentDescription"]')

对应accessibility id定位器的代码如下:

driver.find_element_by_assessibility_id("ContentDescription")

Java版本

driver.findElementByCssSelector("*[description=\"ContentDescription\"]");

对应accessibility id的定位器代码如下:

driver.findElementByAccessibilityId("ContentDescription");
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值