浅谈Android测试技术

一、前言

对于大多数的android商业项目,android开发人员大多都处于功能快速迭代的功能研发和bug修复的循环中,对功能的测试基本都交给专门的测试人员来进行测试,但是我认为,了解和学习android测试相关的技术,为核心代码编写单元测试和自动化测试还是很有必要,能够在版本发布前,代码重构时快速的回归测试,保证代码的正确运行,提高测试的效率。

对于开发人员常用的android测试技术,基本可以分为两类,一类是单元测试,一类是自动化测试。下面将分别对两类测试进行一次粗浅的介绍和分享。

二、单元测试

android中的单元测试基于JUnit,可分为本地测试和instrumented测试,在项目中对应以下两个目录:

1.module-name/src/test/java/.

该目录下的代码运行在本地JVM上,其优点是速度快,不需要设备或模拟器的支持,但是无法直接运行含有android系统API引用的测试代码。

2.module-name/src/androidTest/java/.  

该目录下的测试代码需要运行在android设备或模拟器下面,因此可以使用android系统的API,速度较慢。  

在实际开发过程中,我们应该尽量用JUnit实现本地JVM的单元测试,而项目中的代码大致可分为以下三类:

1.强依赖关系,如在Activity,Service等组件中的方法,其特点是大部分为private方法,并且与其生命周期相关,无法直接进行单元测试,可以进行Ecspreso等UI测试。

2.部分依赖,代码实现依赖注入,该类需要依赖Context等android对象的依赖,可以通过Mock或Robolectric等其它第三方框架实现JUnit单元测试或使用androidJunitRunner进行单元测试。

3.纯java代码,不存在对android库的依赖,可以进行JUnit单元测试。

android的单元测试框架,常用的有以下几个框架和工具:

1、JUnit4

2、AndroidJUnitRunner

3、Mockito

4、Espresso

5、Robolectric

关于单元测试框架的选择,可以参考如图:

浅谈Android测试技术_第1张图片

自动化测试

android的自动化测试,可以使用appium来进行编写。使用appium来进行android自动化测试的编写有如下几个优点:

1、有图形化的操作界面,简单易用。

2、直接展示页面元素的层级,可以方便的找到对应控件的id。

3、可以进行操作录制,直接生成测试代码。

appium的自动化测试需要下载appium-desktop,测试代码可以使用python、java等语言进行编写(使用python需要安装python-client/使用java需要导入java-client)。

使用时,打开appium-desktop,点击启动服务器。

浅谈Android测试技术_第2张图片

浅谈Android测试技术_第3张图片

拉起会话器后,填写参数,必要的参数有platformName,deviceName,如果需要拉起对应app需要填写appPackage和appActivity参数。

其中deviceName可以通过命令行adb devices获取;

appPackage和appActivity有多种获取方式,包括使用adb shell pm list packages来获取包名列表,adb shell dumpsys package 包名 来获取包信息,里面有主活动的信息;也可以打开app后使用adb shell dumpsys window | findstr mCurrentFocus来获取当前应用包名和页面;如果有apk包,可以使用adb version 查找到android sdk目录,在build-tools下,使用aapt dump badging 命令来获取apk包名和活动名。

浅谈Android测试技术_第4张图片

点击启动会话后,会拉起app,同时出现手机上画面的快照。在画面中点击页面中的元素,或者展开元素树,可以找到对应控件的id等属性,在编写自动化测试时,可以通过id找到对应的控件,进行操作。

浅谈Android测试技术_第5张图片

使用appium-desktop有一个很便捷的能力,可以录制操作,直接产生对应的测试代码。使用时,点击开始录制,然后在边上的小屏中选中控件,在右侧进行点击或者输入等操作,完成录制后,就能产生对应的自动化测试代码。

浅谈Android测试技术_第6张图片

浅谈Android测试技术_第7张图片

浅谈Android测试技术_第8张图片

如果是一些复杂的操作,appium提供了TouchAction来模拟界面操作,以java代码为例:

使用Appium需要引入java-client-xx.jar包,在java-client-5.0版本之前,Appium滑动使用的是swipe方法,从5.0之后,Appium已经取消swipe方法,交由TouchAction对象的方法来完成滑动操作。在java-client-5.0版本之前也有TouchAction对象,在java-client-5.0版本之后TouchAction对象的方法使用也有所变化。

使用TouchAction可实现的功能如下:

1.press短按

短按操作是通过入参元素坐标的x,y值完成的。在5.0版本之前直接入参坐标x,y值 press(int x,int y);在5.0版本开始入参是调用PointOption对象的point方法 press(PointOption.point(int x,int y))。

2.longPress长按

长按操作同样是通过入参元素坐标的x,y值完成的,长按操作比较常见的如元素拖动、元素滑动等。在5.0版本之前直接入参坐标x,y值longPress(int x,int y);在5.0版本开始入参是调用PointOption对象的point方法 longPress(PointOption.point(int x,int y))。

3.waitAction暂停

暂停等待。在5.0版本之前使用TouchAction的wait方法,入参是int类型,单位毫秒 wait(2000);在5.0版本开始,已经丢弃了wait方法,使用TouchAction的waitAction方法,入参WaitOptions对象,调用waitOptions方法的入参值是Duration.ofSeconds(1)单位是秒waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1)))。

4.moveTo移动

移动到某坐标位置,与press、longPress配合一起使用。在5.0版本之前moveTo入参为坐标x,y值 moveTo(int x,int y);在5.0版本开始入参是调用PointOption对象的point方法 moveTo(PointOption.point(int x,int y))。

5.release释放

完成press短按、longPress长按、waitAction等待、moveTo移动完成操作后需要使用release方法释放

6.perform执行

调用perform方法表示要执行press短按、longPress长按、waitAction等待、moveTo移动、release释放这些操作

举例:

PointOption startPoint = PointOption.point(1200,1200);

PointOption endPointPoint = PointOption.point(1200,600);

WaitOptions waitOption = WaitOptions.waitOptions(Duration.ofSeconds(1));

new TouchAction<>(driver).longPress(startPoint).waitAction(waitOption).moveTo(endPointPoint).release().perform();

这是一个往上滑动的操作,保持x坐标的不变,y坐标减少,表示从下往上滑动。操作过程是长按--等待1S--滑动--释放--执行

另外元素坐标位置的绝对值因设备大小、分辨率不同,值会不一样(不建议直接使用坐标操作元素),所以要使用相对位置来操作,Appium提供以下方法获取元素相对坐标:

1.获取屏幕大小

int screenWidth = driver.manage().window().getSize().width;

int screenHeight = driver.manage().window().getSize().height;

2.获取元素开始坐标

WebElement element = driver.findElement(By.id("ymxh.main:id/spinner_button"));

Point p = element.getLocation();

//获取元素开始的x,y坐标

int startX = p.x;

int startY = p.y;

3.获取元素宽、高

WebElement element = driver.findElement(By.id("ymxh.main:id/spinner_button"));

//得到元素的宽、高

Dimension d = element.getSize();

int width = d.width;

int height = d.height;

4.得到元素坐标的结束坐标

//得到坐标结束坐标

int endX = startX+width;

int endY = startY+height;

5.得到元素中间坐标

//得到元素中心坐标

int centerX = (startX + endX)/2;

int centerY = (startY + endY)/2;

你可能感兴趣的:(android,单元测试,java)