Android自动化测试入门(二)UI Automator

article/2025/10/24 15:59:06

UI Automator是一个界面测试框架,支持跨进程,几乎可以模拟所有的人工操作。需要运行在4.3或者更高的系统版本上。它的测试代码的编写不依赖于目标应用的内部实现细节,非常适用编写黑盒自动化测试。

UI Automator 测试框架的主要功能包括:

  • uiautomatorviewer: 用来扫描和分析当前设备的当前页面的布局结构,它是sdk中自带的工具位置在 sdk/tools/bin/uiautomatorviewer.bat
  • UiDevice:可以访问目标设备的各种属性,执行设备上的一些操作,比如获取设备的屏幕尺寸,旋转设备,点击设备的返回键,菜单键,home键等。比如点击home键UiDevice.pressHome()
  • UI Automator API:用来编写可靠的测试

UI Automator API中有几个比较重要的类

  • UiObject:代表设备上可见的界面元素,也就是一个一个的控件
  • UiObject2:也是代表界面上的一个元素,它和特定的视图绑定,如果所绑定的视图失效,它也会跟着失效。
  • UiSelector:主要封装了用于界面定位的一系列的方法,主要通过控件的属性来实现控件的定位,用来定位的属性一般有:Text,descirption,class,package,resource-id等。如果搜索到多个满足条件的控件,会返回第一个。属性的搜索可以叠加搜索,比如使用Text筛选出一组控件,还可以使用descirption继续筛选。一般配合UiObject来使用,最终返回一个UiObject对象
  • UiCollection:按照一定的条件列举出界面中所有符合条件的元素,然后在根据内容的文本或者可见内容描述来定位界面上的一个控件或者一个元素。UiCollection对应Android中的ViewGrop
  • UiScrollable:用来处理可滚动控件的滚动操作。
  • Configurator:用来设置用于运行 UI Automator测试的关键参数

官方demo

下面开始使用UI Automator来测试一下系统的计算器,完成一个1+9=10的操作。虽然前面介绍了一堆UI Automator API相关的类,不过用起来的时候很简单,使用官方封装的By类可以很方便的找到对应的界面元素。

打开AndroidStudio,新建一个项目,首先在app下的build.gradle中引入UI Automator的依赖:

androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
复制代码

当新建完一个项目的时候,会看到项目中有两个测试相关的文件夹app/src/androidTestapp/src/test

  • app/src/androidTest 主要是运行在真实手机或者模拟器上的测试,比如集成测试,端到端测试,以及仅靠JVM无法完成的功能验证测试
  • app/src/test 在本地计算机上运行的测试,比如单元测试

UI Automator属于运行在手机端,所以去项目中找到app/src/androidTest目录,在这里面就可以编写UI Automator的测试代码了。新建一个测试类CalculateTest

//执行单元测试的执行类
@RunWith(AndroidJUnit4.class)
//4.3以上系统可以使用
@SdkSuppress(minSdkVersion = 18)
public class CalculateTest {......}
复制代码
  • 指定执行单元测试的执行类为AndroidJUnit4
  • 限制最小运行的sdk是18

一个测试类主要包括三部分,分别用3个注解表示:

  • @Before 测试之前执行,一般用来创建对象或者一些准备工作
  • @Test 用来标注测试方法,可以有多个
  • @After 测试完成之后执行,可以做一些清理工作

想要定位界面上的一个元素,可以通过它的resource-id,包名,文本,类名,内容等信息来定位,如果要测试的应用没有源码,可以通过uiautomatorviewer.bat来获取如下图,点击某个元素,右边就会显示出它的一些信息。

 

//执行单元测试的执行类
@RunWith(AndroidJUnit4.class)
//4.3以上系统可以使用
@SdkSuppress(minSdkVersion = 18)
public class CalculateTest {private UiDevice mUiDevice;//测试执行之前的操作@Beforepublic void startMainActivityFromHomeScreen() {mUiDevice = UiDevice.getInstance(getInstrumentation());//点击home键mUiDevice.pressHome();// 获取启动页的包名,并判断是否为空final String launcherPackage = getLauncherPackageName();assertThat(launcherPackage, notNullValue());//等待启动完成mUiDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), 3000);//启动计算器程序Context context = getApplicationContext();//通过包名创建启动的intentIntent intent = context.getPackageManager().getLaunchIntentForPackage("com.android.calculator2");intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);context.startActivity(intent);//等待启动完成mUiDevice.wait(Until.hasObject(By.pkg("com.android.calculator2").depth(0)),3000);}@Testpublic void calculate() throws InterruptedException, UiObjectNotFoundException {//点击1Thread.sleep(1000);mUiDevice.pressKeyCode(KeyEvent.KEYCODE_1);Thread.sleep(1000);//点击加号mUiDevice.findObject(By.res("com.android.calculator2:id/op_add")).click();Thread.sleep(1000);//点击9mUiDevice.findObject(By.text("9")).click();Thread.sleep(1000);//点击等号mUiDevice.findObject(By.desc("等于")).click();Thread.sleep(1000);//断言验证结果是否正确//模拟器UiObject2 result = mUiDevice.findObject(By.res("com.android.calculator2:id/result"));//华为mate20
//        UiObject2 result = mUiDevice.findObject(By.res("com.android.calculator2:id/formula"));//使用UiSelector的方式查找
//        UiObject result = mUiDevice.findObject(new UiSelector().resourceId("com.android.calculator2:id/result"));Assert.assertEquals("10",result.getText());}@Afterpublic void clearNum() {//测试完成之后,点击clear键清除界面上是数字//模拟器mUiDevice.findObject(By.res("com.android.calculator2:id/clr")).click();//华为mate20
//        mUiDevice.findObject(By.res("com.android.calculator2:id/op_clr")).click();}/*** 获取程序的启动包名* @return*/private String getLauncherPackageName() {final Intent intent = new Intent(Intent.ACTION_MAIN);intent.addCategory(Intent.CATEGORY_HOME);// 通过PackageManager获取启动的包名PackageManager pm = getApplicationContext().getPackageManager();ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);return resolveInfo.activityInfo.packageName;}
}
复制代码
  • 代码中尝试了几种不同方式找到界面上的一个元素控件,比如通过keyCode,通过resourceID,通过text,通过desc。还有别的方式可以进By类中查看。属性筛选可以叠加
  • 代码中一个控件的各种属性通过uiautomatorviewer工具获取,工具位置在sdk/tools/bin/uiautomatorviewer.bat,双击打开就可以了。点击左上角的Device ScreenShot按钮,就能获取当前手机屏幕的快照信息。点击目标控件就能在右边看到该控件的各种属性信息如图。
  • 寻找一个界面控件可以使用mUiDevice.findObject(By...的方式也可以使用mUiDevice.findObject(new UiSelector()....的方式,分别返回UiObject和UiObject2
  • 每个步骤之间最好延时一下,防止测试机还没运行完当前指令后面的指令就执行了。

最后是运行结果:

 

运行完之后可以在下面的地方导出测试报告

 

可以在指定目录生成一个HTML文件,打开文件就可以查看测试的一些信息。

 

注意: 官方建议只有在应用必须要跟系统或者第三方应用有一定的交互的时候,才使用UI Automator来测试。一般情况下如果只是测试自己的应用,建议使用Espresso来代替UI Automator。而且新建一个项目的时候,Espresso相关的依赖都已经在项目中默认引入了,所以官方更推荐我们使用Espresso来测试我们的应用,下一篇来练习Espresso的使用。


最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走: 

下方这份完整的软件测试资料已经上传CSDN官方认证的二维码,朋友们如果需要可以自行免费领取 【保证100%免费】

这些资料,对于从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。希望对大家有所帮助……  


http://chatgpt.dhexx.cn/article/cxoQC0wF.shtml

相关文章

03-vue基础-插值表达式

文章目录 vue插值表达式vue通过data提供数据通过插值表达式显示数据安装vue开发者工具总结 vue插值表达式 本文要讲解的内容如下: 通过data提供数据通过插值表达式显示数据vue开发者工具的安装与使用 vue通过data提供数据 vue中通过template可以提供模板&#xf…

接口自动化和UI自动化:定义、区别及示例代码

目录 1.接口自动化 2.UI自动化 3.接口自动化和UI自动化的区别 4.结论 5.总结 在软件测试领域中,接口自动化和UI自动化是两个常见的测试类型,它们分别用于测试应用程序的不同层面。本文将介绍接口自动化和UI自动化的基本定义、区别以及示例代码。 1…

autojs,ui,界面学习,以及定时脚本页面的构建

注释掉ui或者ui的报错 再来就是认识几个单词,gravity 重力 简单来说就是你所创造的东西你想要它所处的位置在什么地方: left 靠左right 靠右top 靠顶部bottom 靠底部center 居中center_vertical 垂直居中center_horizontal 水平居中 text的一些属性&…

UI自动化测试03

一、警告框处理 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>警告窗口操作</title><script type"text/javascript">// JavaScript一些函数// 定义了一个函数function alterbutton(){alert("…

【UI自动化-3】UI自动化元素操作专题

前言 在熟悉了元素定位之后&#xff0c;我们接下来就要学习对定位到的元素进行操作这项内容了。我简要做了个总结&#xff0c;如下图&#xff1a; 1 基本操作 元素的基本操作有很多&#xff0c;常用的有三个&#xff1a;click&#xff08;点击&#xff09;、clear&#xff…

mysql数据库命令备份还原

一、备份指定表&#xff1a; 在安装有mysql客户端的服务器命令行执行&#xff1a; mysqldump -h mysqlip -uusername -ppassword dbname tablename1 tablename2 > /home/XXXX.sql 如果表特别大&#xff0c;可以加入“nohup &” 来后台执行&#xff0c;以防窗口关闭等…

cmd 下mysql常用的数据库命令

其实如果不想打开mysql软件去操作数据库的话&#xff0c;可以通过DOS命令去操作数据库&#xff0c;也是比较快捷的方式&#xff0c;根据个人的操作喜好而定。 按 winR 键后输入 cmd 进入DOS命令窗口 切换目录到mysql文件下的bin目录&#xff0c;这里以phpstudy_pro 集成环境为…

oracle创建数据库命令

oracle创建数据库命令 1.打开cmd 连接系统默认数据库 2. 创建表空间 CREATE TABLESPACE DATA DATAFILE ‘D:\oracle\DATA\DATA.ORA’ size 10G autoextend on next 1M Maxsize unlimited logging extent management local segment space management auto; 3.创建临时空间 CRE…

css grid 自动高度_十一款游戏教你学会 CSS!

关注“脚本之家”&#xff0c;与百万开发者在一起 网上有很多有助于学习CSS的游戏&#xff0c;本文收集了一些非常实用的免费CSS游戏&#xff0c;希望这些游戏可以帮助你再次体验CSS的乐趣&#xff01; 作者 | Andreas Mller 译者 | 弯月&#xff0c;责编 | 郭芮 出品 | CSDN(I…

CSS设置高度等于动态的宽度

如果子元素根据父元素设置宽度&#xff0c;那么将其高度设置为0&#xff0c;并将padding-bottom设置为百分比&#xff0c;则该子元素的高度将根据它的宽度计算。 <div class"div1"><div class"div2"></div> </div>.div1{width:40…

通关这8个游戏,保证你能精通CSS

在知乎上随便一艘,CSS难学,就会找到很多关于CSS为什么这么难学的提问?各种回答都有,但是我觉得在游戏中学习CSS是最好的,毕竟人的天性就是爱玩。以以 Flexbox 布局为例。弹性容器的属性justify-content可以有12 个不同的值,我们要怎么记住呢?在Flexbox Froggy这款游戏就…

Web前端--HTML+CSS+JavaScript酷炫游戏动漫网页设计

临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大&#xff1f;网页要求的总数量太多&#xff1f;HTML网页作业无从下手&#xff1f;没有合适的模板&#xff1f;等等一系列问题。你想要解决的问题&#xff0c;在这里常见网页设计作业题材有 个人、 美食、 公司、…

css 真正意义上达到height:100%,自适应屏幕高度

最近发现了个用绝对布局写自适应屏幕的写法&#xff0c;让我觉得&#xff0c;之前小程序傻傻读屏幕高再给背景view赋值min-height的写法简直太傻了毕竟能用css解决的问题最好就不要js .shi{position: absolute;top: 0px;bottom: 0;left: 0;width: 20%;background-color: black…

CSS如何设置高度为屏幕高度_HTML和CSS中你应该知道的12个重点难点问题

这12个问题&#xff0c;基本上就是HTML和CSS基础中的重点个难点了&#xff0c;也是必须要弄清楚的基本问题。其中定位的绝对定位和相对定位到底相对什么定位&#xff1f;这个还是容易被忽视的&#xff0c;浮动也是一个大坑&#xff0c;有很多细节。 这12个知识点是我个人认为的…

十一款游戏教你学会 CSS!

网上有很多有助于学习CSS的游戏&#xff0c;本文收集了一些非常实用的免费CSS游戏&#xff0c;希望这些游戏可以帮助你再次体验CSS的乐趣&#xff01; 作者 | Andreas Mller 译者 | 弯月&#xff0c;责编 | 郭芮 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 以…

js 中 clientHeight、scrollHeight 等获取的高度的区别和使用

1、 clientHeight 在盒模型中&#xff0c;代表元素的高度加内边距。 语法&#xff1a; var elmnt document.getElementById("content"); element.scrollHeight;2、scrollHeight 代表元素的像素高度&#xff0c;值等于该元素在不使用滚动条的情况下为了适应视口中所…

【CSS】div等元素height:100%高度为什么不生效

以前一直很郁闷一个问题&#xff0c;为什么设置height:100%不生效&#xff0c;尤其是设置body:height:100%不生效&#xff0c;后来就很少使用了这个了。 今天在学习谷歌地图时关于height:100%看到了解答&#xff1a; In specific, all percentage-based sizes must inherit fr…

css后台页面布局效果

CSS浮动定位 参考:实现左边div固定宽度&#xff0c;右边div自适应撑满剩下的宽度的布局方式&#xff1a;https://www.cnblogs.com/yzhihao/p/6513022.html 下面使用的关键就是使用overflow:hidden开启右侧内容区的BFC&#xff0c;使得左边的浮动元素无法盖住右侧内容区&#x…

前端搭建(HTML+CSS+JS)游戏官网(或其它)页面------实例与代码(示例:游戏官网界面)

前端搭建&#xff08;HTMLCSSJS&#xff09;游戏官网&#xff08;或其它&#xff09;页面------实例与代码&#xff08;示例&#xff1a;游戏官网界面&#xff09; 注意&#xff1a;网页中的示例图片均出自米哈游–原神官网设计&#xff0c;如侵权&#xff0c;联系博主立马进行…

html + css +js:仿原神游戏登录页面(初步)

效果图&#xff1a; html&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conten…