[Android测试] AS+Appium+Java+Win 自动化测试之五:脚本重点技术

时间:2022-12-21 06:00:19

一、了解java-client的方法

看这篇博文: http://blog.csdn.net/niubitianping/article/details/52528146

二、书写规范及注意事项

一条case(测试实例、用例)一般需要包括如下几个要素:

  • 数据准备
    指提前准备测试账号,假数据等
  • 具体操作
    就是case的逻辑内容
  • 验证点
    自动化操作后,UI前后的变化点,比如登录后,跳到首页会出现首页、用户、关于等控件,这些都是验证点
  • 清楚操作结果
    清楚操作结果主要是基于case独立性的考虑,尽可能做到每条case是独立的,这样某条case fail了,也不会对其他case造成影响,当然这样会增加case的粒度,case稳定性会受影响,两者之间可自行平衡。

三、 控件的定位获取

1. 控件的定位

控件的定位的就是获取控件,前两篇文章说了Inspector,现在来说一下uiautomatorviewer,

uiautomatorviewer在sdk的tool目录下,运行uiautomatorviewer.bat即可(可以右击发送快捷方式到桌面)。打开后的界面是这样的:
[Android测试] AS+Appium+Java+Win 自动化测试之五:脚本重点技术

界面详解
[Android测试] AS+Appium+Java+Win 自动化测试之五:脚本重点技术
open: 打开保存的截图文件
device screenshot: 获取当前界面所有控件内容
device screenshot with compressed hierarchy: 选择只获取界面中呈现在你面前的控件
save: 保存界面控件内容到文件

Expand All: 展开全部结点
Toggle naf nodes: 查看不能被uiautomator测试工具访问到的控件。这些控件只设置了有限的属性,所以导致uiautomator无法获取到这些控件。
搜索、上一个、下一个、清除搜索结果、搜索到的数量、坐标

2. 控件的获取

归类为四种元素控件定位的方法

(1). 通过控件id

//返回泛型list
driver.findElementsById("控件的id");

//返回单个控件对象
driver.findElementById("控件id");

(2). 通过控件的值

①. 值就例如TextView的文字
//返回list
driver.findElements();
driver.findElementsByXPath();

//返回单个控件泛型控件对象
driver.findElementByXPath(".//*[@text='Save']");
driver.findElement(By.xpath(".//*[@text='Add Contact']"));
driver.findElement(By.id("你的Id"));
②. 通过contentDescription获取控件

contentDescription就是在android开发的时候,布局里面有个contentDescription属性,填写字符串。这个属性是方便一些生理功能有缺陷的人使用应用程序的。比如我们有一个TextView,有用户看不到东西的,手机的辅助功能就能把这个TextView的contentDescription读出来

//几乎没用到
driver.findElementsByAccessibilityId("控件的contentDescription");
③. Tagname
//这个方法Appium1.0以后已经过时并被以上的findElementByClassName取代了
//请查看https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/migrating-to-1-0.md
driver.findElementByTagName("");
④. WebView的

//通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接
driver.findElementByLinkText()
//这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配
driver.findElementByPartialLinkText()
//cssSelector这种元素定位方式跟xpath比较类似,但执行速度较快
driver.findElementByCssSelector()

(3). 通过控件的类


//例如获取界面的EditText控件

//返回list
driver.findElementsByClassName("android.widget.EditText");

//返回单个控件对象,多个返回第一个
driver.findElementByClassName("android.widget.EditText");
driver.findElement(By.name("android.widget.EditText"));

(4). 坐标

这个返回不了控件,一般用来做滑动,或者点击某个坐标。

//从宽度的3/4 向左滑动到1/4,,  y轴是中间
public void swipeToLeft(int during) {
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
driver.swipe(width * 3 / 4, height / 2, width / 4, height / 2, during);
}

(5). Xpath

这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称(由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位xml或者html页面元素)
有兴趣的学一下: http://www.w3school.com.cn/xpath/
w3school这个网站*了,几年前就在这里学到了很多东西。

关于xpath这种定位方式,webdriver会将整个页面的所有控件进行扫描以定位我们所需要的控件,所以这是一个非常费时的操作,如果你的脚本中大量使用xpath做控件定位的话,将导致你的脚本执行速度降低,所以请慎用。

①. 绝对路径写法:

只有一种,使用右斜杠/

查找根元素的EditText: /android.widget.EditText

②. 相对路径

查找页面根控件://

查找页面上所有的EditText控件://android.widget.EditText

查找页面上第一个TextView控件://android.widget.TextView[1]

查找页面上id为login的控件://[@id=’login’]

查找页面上具有text属性为username的TextView控件://android.widget.TextView[@text=’username’]

查找页面上id为loginLayout的LinearLayout控件下的第一个TextView控件://android.widget.LinearLayout[@id=’loginLayout’]/TextView[1]

③. contains关键字

获取text里面包含保的TextView控件: driver.findElement(By.xpath(“//android.widget.TextView[contains(@text, ‘存’)]”));

④. start-with

获取text里面保开头的TextView控件: driver.findElement(By.xpath(“//android.widget.TextView[starts-with(@text, ‘保’)]));

⑤. text关键字

获取文本为保存的控件: driver.findElementByXPath(“.//*[@text=’保存’]”);

当然xpath还有很多函数,可以去w3school那里看看手册。这里就不多讲了

(6). 获取界面的XMl文件

driver.getPageSource();

getPageSource函数,可以把当前页面的元素以XML的方式打印出来,建议大家在找不到view的相应属性的时候就调用该函数来慢慢查找了。

四、控件等待

例如登录,需要网络返回,需要一个等待时间,这个怎么确定呢? 这个时候等待就出来了,等到分为三种:

1. 显示等待(Explicit Wait)

利用AndroidDriverWait(这个类是需要自己封装的,下一篇文章会说)。 显式等待的意思就是,传递一个控件和时间给它,如果这个控件在规定时间内出现了就返回,或者时间到了这个控件还没出来就抛出异常。

2. 隐式等待(Implicit Wait)

driver.manage().timeouts().implicitlyWait(time, TimeUnit.SECONDS);

implicitlyWait() 不是休眠,是全局设置超时时间,在findelement或者findelements的时候,首先去找控件,如果没有找到,判断时间否超过implicitlyWait()设置了的时间,如果没有超过,则再次找这个元素,直到找到元素或者时间超过最大阀值。那我们就可以设定一个比较长的超时时间,但同时也不会让程序白白的等待。默认是250ms。

3. 线程休眠

调用java的sleep(); 强制等待规定时间再运行之后的代码。

    Thread.sleep()

五、多个测试用例case

例如我们要实现登录,登录完成之后注销,其实这里是两个功能了,我们就可以写多个测试用例了,然后根据设置优先级来依次运行用例

  1. 编写测试用例
  2. 设置优先级

例如:

    @Test(priority = 0)
public void one() throws InterruptedException {

print("第一个优先级,");
}

@Test(priority = 0)
public void two() throws InterruptedException {

print("第二个优先级,在one()执行完毕之后执行");
}

@Test(priority = 1)
public void three() throws InterruptedException {

print("第三个优先级,在two()执行完毕之后执行");
}

PS:
多个用例的注解回调方法是 例如上面的代码:
beforeMethod - one() - afterMethod - beforeMethod - two() - afterMethod - beforeMethod - three() - afterMethod

每个Test前后都对回调beforeMethod和afterMethod

六、 断言

1. what? 什么是断言?

这个名字有点懵,简单来说断言就是, 判断值是否为预料的那样,不一样的话就抛出错误,终止运行程序。

常用的断言方法有:

  • assertTrue:判断是否为True。

  • assertFalse:判断是否为false。

  • assertSame:判断引用地址是否相同。

  • assertNotSame:判断引用地址是否不相同。

  • assertNull:判断是否为null。

  • assertNotNull:判断是否不为null。

  • assertEquals:判断是否相等,Object类型的对象需要实现haseCode及equals方法。

  • assertNotEquals:判断是否不相等。

  • assertEqualsNoOrder:判断忽略顺序是否相等。

其实平时用assertEquals这个就可以了。

例子:

@Test
public void test(){
String str = "123";
Assert.assertEquals(str,"12");
print("断言之后的内容");
}

上面这个执行,就会发生这样的结果:

[Android测试] AS+Appium+Java+Win 自动化测试之五:脚本重点技术