其他测试框架 APP 自动化框架设计分享

testly · 2016年01月02日 · 最后由 zhanglimin 回复于 2018年02月09日 · 3420 次阅读
本帖已被设为精华帖!

APP 自动化框架设计分享

在分享前 首先先祝大家新年快乐,再祝 testerhome 继续这样越来越好~~

前言:

最近几个月都很忙,这一陈会延续到明年4月~~元旦都在加班~所以我很”焦灼“!
下面是分享的这个是我个人的想法,可能大家觉得不合理的地方都可以提出来,我会虚心接纳大家的建议~!大家互勉~谢谢!

框架需要解决的问题:

• 渠道包->多渠道包核心用例自动化

• 多设备覆盖安装,安装卸载更新等测试

• 多设备核心用例适配测试

• 验证主要页面(包括 webview)检查是否加载成功

• 离线主流程覆盖

• 一些重复性操作可以通过框架简单实现

框架目标定位:

• 让 Tester 无需编写代码 通过简单数据驱动方式实现通用简单的自动化

• 跟开发约定一些 UI 上的元素标准和规范建立自动化规范流程化

• 结合实时抓包组件和性能监控插件方便分节点定位问题

• 自动异常捕获,CrashLog 收集汇总等等

• 每一步都有 Log、截图(甚至做到录制)方便复现问题

• 实行单台服务器多设备并行 根据配置不同机型执行不同 case 并统一会汇总报告

关于自动化的一些疑问:

--->自动化的时候用例错误了怎么办?下面的会继续跑么?

当发生错误时会优先检查检查设备状态,网络状态当用例发生错误时(如果是webview会等待20秒刷新页面)回到上一步等待30s切换回来重复执行,如果还是发生错误会在报告说明,继续执行下一条用例

--->我们怎么去用这个东西呢?数据我们怎么去准备?数据准备麻烦么?

当测试人员有自动化测试需求时只需要配置好数据模板在网页选择执行的机器点击开始运行即可


数据准备:数据准备为每一个自动化测试工程师的难题,因为每一步动作都需要用uiautomatorviewer  或者hierarchyviewer 去一个一个找元素
针对这个我们解决方法是:跟开发约定界面控件命名规范,元素控件值按我们约定的格式命名   只需打开app找到需要点击控件名称的首字母填入文档中即可(当然这种办法只会解决部分问题)

自动化跑完之后如果发生异常了怎么办?自动化跑完之后发生异常我们如何分析?

根据目前设计的框架,三种定位问题的方法:

>1,第一是跑自动化时会实时抓取Devices设备所有logcat日志并解析异常Log(包括crash日志)

>2,第二是跑自动化时会实时截取实时app发送的所有API的内容以及状态方便定位区分前后端问题

>3,第三是跑自动化时会实时截图甚至可以录制视频,还有测试人员自定义的一些检查点作为主要的定位路径

关于 UI 控件命名规范::

跟开发约定界面控件命名规范,元素控件值按我们约定的格式命名 这样可以提高自动化效率,以及减轻版本迭代自动化工作量!
以下示例:

以页面为整体 控件为类型 各类型的控件拼音首字母为控件标识 统一格式为:应用缩写页面名称控件类型_控件首字母

button格式:

比如主页的搜索按钮 控件的格式为:TT_Home_ button_Ss

Input 格式:

比如登录页面用户名输入框:TT_Login_input_Zh

image格式:

比如推荐页面图片“每日十首”:TT_ Recommend_ image_mrss

这样的好处就是我们不需要用 uiautomatorviewer 或者 hierarchyviewer 去一个一个找元素 碰到需要点击的元素控件只需要根据页面上的控件首字母,就算页面改动我们也只需要对着 app 上面在模板内改动的部分修改一下数据即可~

流程图:

用户需要执行:
根据元素设计case 
制定预期
选择机型并开始运行

启动 log:

环境初始化:

Appium 启动封装起来,在每次启动前 检查初始化端口以及adb进程  再分配 Port  和BootPort

AndroidDevices Capabilities  里面四个可变量参数可以通过adb取到(device 列表和对应的型号放在Map内)

设计一个 DriverModel

package org.alimusic.driver;

public class DriverModel {
    private String device="Android";
    private String deviceName;
    private String platformName="Android";
    private String platformVersion;
    private String appPackage="com.xxx.ttpod";
    private String appActivity="com.xxx.ttpod.EntryActivity";
    public String getDevice() {
        return device;
    }
    public void setDevice(String device) {
        this.device = device;
    }
    public String getDeviceName() {
        return deviceName;
    }
    public void setDeviceName(String deviceName) {
        this.deviceName = deviceName;
    }
    public String getPlatformName() {
        return platformName;
    }
    public void setPlatformName(String platformName) {
        this.platformName = platformName;
    }
    public String getPlatformVersion() {
        return platformVersion;
    }
    public void setPlatformVersion(String platformVersion) {
        this.platformVersion = platformVersion;
    }
    public String getAppPackage() {
        return appPackage;
    }
    public void setAppPackage(String appPackage) {
        this.appPackage = appPackage;
    }
    public String getAppActivity() {
        return appActivity;
    }
    public void setAppActivity(String appActivity) {
        this.appActivity = appActivity;
    }

    public DriverModel(String device, String deviceName,String platformName,String platformVersion) {
        super();
        this.device = device;
        this.deviceName = deviceName;
        this.platformName = platformName;
        this.platformVersion = platformVersion;

    }

    public DriverModel(String deviceName,String platformVersion) {
        super();
        this.deviceName = deviceName;
        this.platformVersion = platformVersion;

    }

    public DriverModel() {
        super();
        // TODO Auto-generated constructor stub
    }
}

Factory(三种情况):


package org.alimusic.driver;

import io.appium.java_client.android.AndroidDriver;


/**
 * 
 * @author testly
 *
 */
public class DrvierSetting {



    public abstract class Factory{
        public abstract DriverModel createDriverModel();
        public abstract DriverModel createDriverModel(String device,String deviceName,String platformVersion,String platformName);
    }

    public static class SimpleFactory{
        public DriverModel createDriverModel() {
            DriverModel model = new DriverModel();
            return model;
        }

        public static DriverModel createDriverModel(String device,String deviceName,String platformVersion,String platformName){
            DriverModel model = new DriverModel(device,deviceName,platformVersion,platformName);
            AndroidDriver driver = DrvierStart.Start(model);
            return model;
        }

        public static DriverModel createDriverModel(String deviceName,String platformVersion){
            DriverModel model = new DriverModel(deviceName,platformVersion);
            return model;
        }
    }
}


Derices StartUp


public static AndroidDriver Start(String devicename,String ip, int port)
       {       
           AndroidDriver driver = null;
           String platformName = GetEnvironmentVariable.DevicesVersion(devicename);
           DriverModel model = SimpleFactory.createDriverModel(devicename,platformName);
           DesiredCapabilities capabilities = new DesiredCapabilities(); 
           capabilities.setCapability("device",model.getDevice());
           capabilities.setCapability("deviceName",model.getDeviceName());              
           capabilities.setCapability("platformVersion", model.getDeviceName());  
           capabilities.setCapability("platformName",model.getDeviceName());  
           capabilities.setCapability("appPackage", model.getAppPackage());  
           capabilities.setCapability("appActivity", model.getAppActivity());
           try {
               driver = new AndroidDriver(new URL("http://”+ip+“:“+port+“/wd/hub"), capabilities);
           } catch (MalformedURLException e) {
               System.out.println("connection error!");
               e.printStackTrace();
           }
           return driver;

      }    

数据配置定制:

前台网页 会根据用户选择配置去自动设置配置文件

检查:

检查是我认为最难!~

目前我的设想是:

1,用户自定义检查
2,网络传输层检查(自动化时实时抓包)
3,logcat实时抓取异常log(区粉设备)
4,截图录制、系统抛错,图片解析对比等

通过遍历文件内的数据文件的一条数据既是一个动作和检查点

欢迎一起交流,一起进步 可以关注我的微信公众号:“测试开发进阶” - 点我关注

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 37 条回复 时间 点赞

你们这都是重复造轮子啊,厂内的不用,自己搞。

UI 自动化你好,UI 自动化再见
你们这都是重复造轮子啊,厂内的不用,自己

#1 楼 @lihuazhang @monkey

是呀集团的东西已经有了,用过,但是。。。。
很多都不可控呀,比如我想 手机做个代理 app 指向我们这边日常测试环境,在摩天轮上就很难实现!
还有集团的方式还是要有一些不一样,case 的管理和控制有一些局限, 另外检查项和结果精细度也还好吧!~
当然我说的这些不是说我的能比集团的好,只是自己写的抛开好不好用,慢慢改善,总归能学到许多东西

新年快乐!
这是新年的一份大礼,谢谢 testly,写的很好👏👏👏👏。
你那些流程图用什么画出来的?

#3 楼 @testly 集团东西多了。。也没有说摩天轮呀。。摩天轮都已经废掉了好么。。。

嗯,我也觉得可以把你的特色的地方凸显出来。与别人做的不一样的优势!
可能会是我们学习的点!

#6 楼 @monkey 我们这边还在用~集团东西是很多,除了中间件自带的平台 真正能给我们用的却很少~!

#7 楼 @anikikun
其实跟大多数公司大部分都差不太多,
区别就是:
根据数据去转化脚本
结合自动抓包,自动抓取 crash 日志 和 logcat 日志 还有一些检查方式

后面一点点分享出来、

我来给你手动点赞了

testly #11 · 2016年01月03日 Author

#10 楼 @75281920 多谢!

点赞,谢谢分享!有一个问题想请教下,控件命名规范目前这种做法还是有一定的 android 基础,能否做一个遍历控件的工具,傻瓜式的供测试执行人员使用?

testly #13 · 2016年01月04日 Author

#12 楼 @big 深度遍历控件工具后期会考虑吧~其实用 uiautomatorviewer 或者 hierarchyviewer 基本能用, 只是缺少层级对应

--- “跟开发约定一些 UI 上的元素标准”
请问这个在你的团队中实践中效果如何,开发人员会按照这个标准去执行吗?
这样会不会增加开发的成本(一些控件命名对开发其实是无用的)?

testly #15 · 2016年01月04日 Author

#14 楼 @spider 这需要去推,把这种需求与 pd 交涉,在产品开发前敲定! 这样对我们后期的实施和迭代有很大的帮助

#6 楼 @monkey 谁说摩天轮废掉了。摩天轮屌的地方在于配合 atlas。。。@testly 指向测试环境写个 checkbox 选择不就行了。。。。UI 自动化你好,UI 自动化再见

UI 自动化你好,UI 自动化再见

楼主的这类自动化框架我也在做。。可能是我一上手就是拿到半成品,再基于半成品来写的,所以我不知道到厂内有什么好东西。。就科普

testly #19 · 2016年01月13日 Author

#18 楼 @m13890 这个说实话,看你自己怎么想,厂内毕竟是厂内的,自己开发的是跟着你自己走的~
厂内的很多东西可以借鉴,如果考虑当下而且时间比较紧的话最好是借鉴吧!

#19 楼 @testly 我完全是一脸茫然,半路加入后除了基础的东西我基本修改了逻辑上的处理。团队约定完全做不到,都是我围绕着开发来开发,ID 命名一片混乱还随时在变。话说回来,楼上几位为什么好像很反感 UI 自动化的样子

谢谢, 启发很大,已收藏

新人,想请教下集团和厂内指的是?

—— 来自 TesterHome 官方 安卓客户端

UI 自动化的稳定性要如何提高呢?

#23 楼 @testly 多谢`~ 听说阿里里面测试 Android 用的不是 Robotium 架构的么?

testly #26 · 2016年03月08日 Author

#25 楼 @jjzhoujun 在每个事业部选择不一样

UI 自动化成功率多少?

testly #28 · 2016年03月09日 Author

#27 楼 @quqing 阶段性评估
内测较低,公测比较稳定,灰度 case 必须为 90% 以上

#28 楼 @testly 90%?这么高?请问你们用哪些方案来提高 UI 案例稳定性的?

#29 楼 @quqing 首先我们的目标 覆盖率只有 10% 核心用例 而且没有一些复杂的检查点 结合接口去做的校验

@testly 请教下,你在正文中说到 让 Tester 无需编写代码 通过简单数据驱动方式实现通用简单的自动化
想问下在这里你实现的怎样了?有没有实现逻辑的判断或者一些循环之类的

testly #32 · 2016年03月18日 Author

#31 楼 @huanzhijin 已经简单实现了,目前每一个 case 都是流程 case,
流程 case 都是 步骤组成的,检查的方法也比较简单,比如执行完登录之后 根据数据模板提供的 元素去找到对应的文本跟预期结果作比对,等等。。。

#1 楼 @lihuazhang @monkey 大公司就是永远在造轮子,想要把一个工具推到每个 bu,每个事业部,太难,没有最好的工具,只有最适合的, 另外每个工程师都要成长,leader 需要业绩

—— 来自 TesterHome 官方 安卓客户端

#33 楼 @taki 是的,其实所谓的很多人说大公司慢,就是慢在这里,但是很多人浑然不知,回过头才发现就是在原地踏步,与人斗其乐无穷

#34 楼 @monkey 如果都用集团的一套工具,其他团队就没有创新等等,单纯的功能测试,很难出业绩,统一的话,最好还是每个部门都出人参与,才能真正把工具落地,才能把基层真正的需求融入到工具中

#35 楼 @taki 前者是现状,后者是理想。。。or。。。幻想。。

部门重复制造轮子有时候也是从安全的角度想的,而且需要多一点的需求时,BAT 都是按时收费的。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册