Android TV磁贴类app自动化框架二次改造(基于UiAutomator)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android TV磁贴类app自动化框架二次改造(基于UiAutomator),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6254字,纯文字阅读大概需要9分钟。
内容图文
![Android TV磁贴类app自动化框架二次改造(基于UiAutomator)](/upload/InfoBanner/zyjiaocheng/1070/c601ae24c1dd4cd1868393a23a580d0d.jpg)
简介
项目一直是手工测试为主,加上一直是TV类应用,很多自动化工具都没有针对TV类项目做很好的适配,所以只有自己动手了。主要针对项目的特殊性进行了部分改造,不一定适用于其他项目。(涉及隐私,就不提供json文件和软件名字啦)
痛点
1.非标准控件的难处
通过uiautomatorviewer获取到的不一样的磁贴,属性全部相同(除了坐标点),意味着没法通过id和class+index方式获取,text属性为空,也就没有办法通过byText的方式获取uiobject,高度定制的磁贴,让自动化很为难,如果通过坐标点,太坑爹,不能跨设备,还是坑。
2.TV类应用没有触摸操作
TV类安卓程序,主要面向的是遥控器,也就是接收的是keyevent,所以touch事件显得不这么全面,为了最接近用户,还是选择用key来做自动化。
架构模块
解析模块
从服务器解析json文件格式,包装成实体类CellInfo,返回一个包含磁铁信息的List。一个磁铁对应一个CellInfo,一个CellInfo需要提取的信息有
- x坐标
- y坐标
- 所属的Tab分类页
- 每个磁铁的说明标签
所以对应的定义如下:
package launcherClick.model;
publicclass CellInfo {
private String label;
private String tab;
public String getTab() {
return tab;
}
publicvoidsetTab(String tab) {
this.tab = tab;
}
privateint x;
privateint y;
public String getLabel() {
return label;
}
publicvoidsetLabel(String label) {
this.label = label;
}
publicintgetX() {
return x;
}
publicvoidsetX(int x) {
this.x = x;
}
publicintgetY() {
return y;
}
publicvoidsetY(int y) {
this.y = y;
}
}
解析用的是第三方开源库org.json,对应的解析代码如下:
package launcherClick;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import Utils.IOUtils;
import Utils.Println;
import launcherClick.model.CellInfo;
public class AMetroParse {
public static List<CellInfo> startParse(String url) {
String str = IOUtils.readFromNet(url);
if(str==null){
return null;
}
JSONObject jsonObject = new JSONObject(str);
List<CellInfo> list = new ArrayList<CellInfo>();
JSONArray _tabs = jsonObject.getJSONArray("tabs");
for(int i = 0;i<_tabs.length();i++){
String tab = _tabs.getJSONObject(i).getString("label");
JSONArray _cells = _tabs.getJSONObject(i).getJSONArray("cells");
for(int j=0;j<_cells.length();j++){
CellInfo cellInfo = new CellInfo();
cellInfo.setX(_cells.getJSONObject(j).getJSONObject("location").getInt("x"));
cellInfo.setY(_cells.getJSONObject(j).getJSONObject("location").getInt("y"));
cellInfo.setLabel(_cells.getJSONObject(j).getJSONObject("content").getString("label"));
cellInfo.setTab(tab);
list.add(cellInfo);
}
}
return list;
}
}
坐标转换模块
这部分的工作是把上一步骤解析后的实体类进行提取和处理,主要处理的内容是根据x y坐标计算磁铁移动量,更具x的极大值和分类页做跨分类移动的偏移计算以及一些其他处理。
通过x y计算偏移比较简单,只是简单计算距离:
for (CellInfo cellInfo : list) {
if (cellInfo.getLabel().contains(label)
&& cellInfo.getTab().contains(tab)) {
int x = cellInfo.getX();
int y = cellInfo.getY();
new Println("x:" + x + " " + "y:" + y + " " + "偏移量" + _offset);
// x方向for (int i = x + _offset; i > 1; i--) {
new Println("→" + " count is " + (x + _offset));
keyRight();
}
// y方向for (int i = y; i > 1; i--) {
new Println("↓");
keyDown();
}
}
}
恩,里面有个偏移量,跨分类用的,偏移量是通过每个分类下磁铁最大值得出来的,每一个分类最后一个磁铁的x值即为最大值,遍历当前分类下的所有磁铁的x,如果大于后面一个,则放在前面,下次再用这个值去比较下面的x值。忘记这是什么排序算法了…囧…当然,也可以用Collections的自带的算法。
private
int
togicOffset(String tab) {
int lineLenth = 0;
List<CellInfo> list = AMetroParse
.startParse("我是隐藏的接口");
for (CellInfo cellInfo : list) {
if (cellInfo.getTab().contains(tab)) {
int x = cellInfo.getX();
lineLenth = lineLenth >= x ? lineLenth : x;
}
}
return lineLenth;
}
那么通过上面的排序之后,就可以得到每个分类的偏移量,这样对于后面的分类磁贴,就可以知道磁贴在整体的真正位置啦,于是就可以开始移动了。
for (CellInfo cellInfo : list) {
if (cellInfo.getLabel().contains(label) && cellInfo.getTab().contains(tab)) {
int x = cellInfo.getX();
int y = cellInfo.getY();
new Println("x:" + x + " " + "y:" + y + " " + "偏移量" + _offset);
// x方向for (int i = x + _offset; i > 1; i--) {
new Println("→" + " count is " + (x + _offset));
keyRight();
}
// y方向for (int i = y; i > 1; i--) {
new Println("↓");
keyDown();
}
}
}
图片比较模块
来源于monkeyrunner的思路,原理是计算两个bitmap的长宽,然后提取出里面每个像素的像素值,如果相同,相似度+1,最后再除以总像素值(比如1280x720),这样就可以把相似程度转为一个一个可以衡量的具体值了,那么判断这个界面是不是我需要点击的时候,只需要截屏当前图片和预期的图片对比,相似度达到100的时候就认为是正确的。当然也提供了局部比较的功能,比如获取不到数据的异常提示。那么代码如下,提供了多种重载的方法以及两个assert判断。
package Utils;
import junit.framework.Assert;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
publicclassImageCompare {publicstaticvoidAssertBitmapEqual(Bitmap bitmap0, Bitmap bitmap1){
/**
* 百分百图片相同断言-.-
*/
Assert.assertEquals(100, ImageCompare(bitmap0,bitmap1));
}
publicstaticvoidAssertBitmapNotEqual(Bitmap bitmap0, Bitmap bitmap1){
/**
* 百分之零图片相同断言
*/
Assert.assertEquals(0, ImageCompare(bitmap0,bitmap1));
}
publicstaticintImageCompare(String path0,String path1) {
/**
* 提供根据路径直接比较
*/
Bitmap bitmap0 = BitmapFactory.decodeFile(path0);
Bitmap bitmap1 = BitmapFactory.decodeFile(path1);
return ImageCompare(bitmap0,bitmap1);
}
publicstaticintImageCompareChild(Bitmap bitmap0, Bitmap bitmap1,int x,int y,int width,int height) {
/**
* 裁剪子图并比较,主要是为了解决拉取动态数据不同,但是局部提示不变的比较场景。
*/
Bitmap bitmap00 = bitmap0.createBitmap(bitmap0, x, y, width, height);
Bitmap bitmap01 = bitmap1.createBitmap(bitmap1, x, y, width, height);
return ImageCompare(bitmap00,bitmap01);
}
publicstaticintImageCompare(Bitmap bitmap0, Bitmap bitmap1) {
/**
* 比较的主函数
* 只能比较相同长宽的图片,不相等返回-1失败
* 相似度为1~100
* 原理是提取每一个像素点比较,整张图相似度取决于像素点相同个数,所以还是比较准确的
*/int picPct = 0;
int picCount = 0;
int picCountAll = 0;
new Println("begin to compare");
if (bitmap0 == null || bitmap1 == null) {
new Println("null bitmap");
return -1;
}
if (bitmap0.getWidth() != bitmap1.getWidth()
|| bitmap0.getHeight() != bitmap1.getHeight()) {
return -1;
}
new Println("宽度为:" + bitmap1.getWidth() + "高度为:" + bitmap1.getHeight());
for (int j = 0; j < bitmap1.getWidth(); j++) {
for (int i = 0; i < bitmap0.getHeight(); i++) {
if (bitmap0.getPixel(j, i) == bitmap1.getPixel(j, i)) {
picCount++;
}
picCountAll++;
}
}
int result = (int) (((float) picCount) / picCountAll * 100);
new Println(picCount + "/" + picCountAll);
new Println("相似度为:" + result);
return result;
}
}
异常&&其他模块
定义了一些异常类,主要功能用于提示,这个提示的作用后面会用到。
增加了启动应用和关闭应用的方法,原理是用到了shell命令。
Runtime.getRuntime().exec("am start -n 我是包名隐藏者");
初始化方法,主要用于异常时能够一键重新开始,以及磁贴复原功能,还有其他一些小的处理就不多说啦,下面开始持续构建。
自动化的持续集成
还是那句话,不持续集成的自动化不是自动化,所以这里介绍的是基于jenkins的自动化集成,其实UiAutomator做集成还是很容易的,只要把jar包放在一个固定的目录,然后shell命令执行就完事了。
然后定时任务自己选吧,构建失败的邮件提醒这里设置的是,上面我自定义的异常类,当控制台输出我的异常类,那么会认为不通过,然后触发邮件提醒。
那么至此,一个较为完整的流程就完成啦,那么在此框架上组员们(就我一个)就可以更进一部去完善二级页面的自动化用例了。
原文:http://blog.csdn.net/cloud_huan/article/details/51204348
内容总结
以上是互联网集市为您收集整理的Android TV磁贴类app自动化框架二次改造(基于UiAutomator)全部内容,希望文章能够帮你解决Android TV磁贴类app自动化框架二次改造(基于UiAutomator)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。