自动定位失败_自动化工具之Appium元素操作小技巧

背景

      appium自动化工作中,元素操作最常用的就是Id/xpath,因为【appium1.5.0后,不支持使用name定位】所有大家在工作中使用id/xpath定位;如果还是想用name定位,需要修改源码,具体大家自己去查,但在工作中id/xpath已经够用。

        今天介绍目前我工作最常用的一些方法,希望能帮到大家,少走弯路。

TestNG常用注解

     为什么要学习testng注解,因为在写测试类的时候需要,通过小小注解让他帮我们干活,所有需要先了解下:

TestNG简单介绍几种注解

注解描述
@BeforeSuite在该套件的所有测试都运行在注释的方法之前,仅运行一次
@AfterSuite在该套件的所有测试都运行在注释方法之后,仅运行一次
@BeforeClass在调用当前类的第一个测试方法之前运行,注释方法仅运行一次
@AfterClass在调用当前类的第一个测试方法之后运行,注释方法仅运行一次
@BeforeTest注释的方法将在属于test标签内的类的所有测试方法运行之前运行
@AfterTest注释的方法将在属于test标签内的类的所有测试方法运行之后运行
@BeforeGroups配置方法将在之前运行组列表。此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行
@AfterGroups此配置方法将在之后运行组列表。该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行
@BeforeMethod
释方法将在每个测试方法之前运行
@AfterMethod注释方法将在每个测试方法之后运行
@DataProvider标记一种方法来提供测试方法的数据。注释方法必须返回一个Object [] [],其中每个Object []可以被分配给测试方法的参数列表。要从该DataProvider接收数据的@Test方法需要使用与此注释名称相等的dataProvider名称
@Factory将一个方法标记为工厂,返回TestNG将被用作测试类的对象。该方法必须返回Object []
@Listeners定义测试类上的侦听器
@Parameters描述如何将参数传递给@Test方法
@Test将类或方法标记为测试的一部分,此标记若放在类上,则该类所有公共方法都将被作为测试方法

注意:

在使用@test注解用例的时候,最好使用T001做方法名称,这样test在跑的时候会根据0--1这样的开始执行。

455db0baa13efd686109da7de5e257bb.png

如果想改变执行规则可以增加priority注解

@Test(description = "初始化登录启动", testName = "进入首页", priority = 0)

说明:

description:表示注释

testName:标志测试类

priority:表示执行顺序

实战

案例一

下载京东APP

启动app就能看到,每次启动都会提示这个,那么在写代码的时候咱们把这个方法:

bc01db767dd5bf59e3e88f523f67786a.png

类似这样的在写测试用例的时候可以这样写,之后其他类集成这个即可:

68455067b968781f66639db28a438910.png

技巧二

如图:

6c580a6691cd55c3865ac683b664c1bf.png

类似中间这些应该怎么定位才最好,我们观察下面定位,可以采用xpath定位

1fce83520894a39b49b6296e79a72206.png

代码示例

/**

* 点击购物车

*/

public void clickbaibao(AndroidDriver<AndroidElement> driver) {

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "百宝箱");

String[] name = {"京东超市", "数码电器", "京东服饰", "京东生鲜"};

for (int i = 0; i < name.length; i++) {

element = driver.findElement(By.xpath("//android.widget.TextView[@text='京东超市']".replace("京东超市", name[i])));

element.click();

}

}

点击进入京东超市后再判断是否登录成可以:

83a44da2bb7575a6e8a37d093ea5a7e0.png

上可以采用id定位

dd964ac99f4cef7340488cde333a65f2.png

代码示例

编写通用判断类

/**

* 统一判断是否通过

*

* @param driver 传driver

* @param elemn 定元素

* @param des 描述

*/

public void assertTrue(AndroidDriver<AndroidElement> driver, String elemn, String des) {

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp(elemn), des);

element = driver.findElement(getByLocator.getLocatorApp(elemn));

String text = element.getText();

if (text != null) {

Assert.assertTrue(true, des + "验证成功");

} else {

//如果失败系统会自动截图

Assert.fail("跳转失败");

}

}

完整代码

元素:

#点击首页clickCart=xpath>>//android.view.View[@content-desc='首页']#跳转成功assertTitile=id>>com.jingdong.app.mall:id/fd#退回home_back=id>>com.jingdong.app.mall:id/fe#百宝箱名字Jingdong_supermarket=xpath>>//android.widget.TextView[@text='京东超市']

代码示例

private GetByLocator getByLocator;

private WebElement element = null;

/**

* 构造函数

*/

public CartProvider() {

this.getByLocator = new GetByLocator("loginElement.properties");

}

/**

* 点击首页

*/

public void clickCart(AndroidDriver<AndroidElement> driver) {

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "点击首页");

element = driver.findElement(getByLocator.getLocatorApp("clickCart"));

element.click();

}

/**

* 点击百宝箱

* @param driver

*/

public void clickbaibao(AndroidDriver<AndroidElement> driver) {

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "百宝箱");

String[] name = {"京东超市", "数码电器", "京东服饰", "京东生鲜"};

for (int i = 0; i < name.length; i++) {

element = driver.findElement(getByLocator.getLocatorApp("Jingdong_supermarket".replace("京东超市", name[i])));

element.click();

//断言

assertTrue(driver, "assertTitile", name[i] + "跳转成功");

//退回

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("home_back"), "退回");

driver.findElement(getByLocator.getLocatorApp("home_back"));

}

}

/**

* 统一判断是否通过

*

* @param driver 传driver

* @param elemn 定元素

* @param des 描述

*/

public void assertTrue(AndroidDriver<AndroidElement> driver, String elemn, String des) {

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp(elemn), des);

element = driver.findElement(getByLocator.getLocatorApp(elemn));

String text = element.getText();

if (text != null) {

Assert.assertTrue(true, des + "验证成功");

} else {

//如果失败系统会自动截图

Assert.fail("跳转失败");

}

}

测试类

import appout.appcase.data.CartProvider;

import org.testng.annotations.Test;

/**

* @author liwen

* @Title: CartTest

* @Description: 测试类

* @date 2019/11/23 / 19:57

*/

public class CartTest extends BestRuner {

CartProvider cartProvider = new CartProvider();

@Test(description = "点击首页百宝箱", testName = "点击百宝箱", priority = 1)

public void T002() {

cartProvider.clickHome(driver);

cartProvider.clickbaibao(driver);

}

}

xpath语法

https://www.w3school.com.cn/xpath/xpath_syntax.asp

遍历技巧二

观察如图:如果想遍历推荐分类每个商品应该怎么写?是每个写一个还是执行一个list之后挨个遍历?还是这么写?

4834d90ad803f40bed632c96a8150361.png

观察定位方式:

61ac8e7cd3f62dd7d3de1186212b6da2.png

在工作中我是这样写的

#分类categorylist=id>>com.jd.lib.category:id/a1z

代码

/**

* 分类写法

* @param driver

*/

public void categorylist(AndroidDriver<AndroidElement> driver) {

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("categorylist"), "遍历分类");

//获取全部数据挨个遍历

List<AndroidElement> categorylist = driver.findElements(getByLocator.getLocatorApp("categorylist"));

for (int i = 0; i < categorylist.size(); i++) {

String text = categorylist.get(i).getText();

//输出遍历name

LogUtil.info(text);

categorylist.get(i).click();

}

}

属性判断写法

查看如下图:想知道该商品是否关注,应该这么写?

通过观察他的属性:

4083a583770d2275d38662cf572ec1ab.png

收藏属性

547d00b47233a406b590a17ee66c8427.png

通过观察,代码写法:

1、获取该元素的地位

902a7c929396fff2f929ddb0f5e2bf7d.png


元素为:

#收藏productdetail=id>>com.jd.lib.productdetail:id/afr

简单代码

/**

* 收藏

*

* @param driver

*/

public void productdetail(AndroidDriver<AndroidElement> driver) {

WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("productdetail"), "收藏");

AndroidElement detail = driver.findElement(getByLocator.getLocatorApp("productdetail"));

String attribute = detail.getAttribute("selected");

if (attribute.equals(true)) {

LogUtil.info("目前商品收藏,目前的属性为:" + attribute);

} else {

LogUtil.info("商品没有收藏,目前的属性为:" + attribute);

}

}

通过得取属性就知道下一步怎么操作

总结

       上面简单介绍几个测试用例写法,随着大家不断熟悉UI自动化,技能会逐渐增加,希望给大家带去一点帮助;

送大家一篇文章

庖丁解牛

先秦:庄周

  吾生也有涯,而知也无涯 。以有涯随无涯,殆已!已而为知者,殆而已矣!为善无近名,为恶无近刑。缘督以为经,可以保身,可以全生,可以养亲,可以尽年。

  庖丁为文惠君解牛,手之所触,肩之所倚,足之所履,膝之所踦[yǐ],砉[huā]然向然,奏刀騞[huō]然,莫不中音。合于《桑林》之舞,乃中《经首》之会。

  文惠君曰:“嘻,善哉!技盖至此乎?”

70523c3acc62659e82bc74212d535a04.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值