测试基础 移动端自动化多机并行测试-Part1

xiaomingpapapa · 2018年12月14日 · 最后由 菜白小 回复于 2020年12月21日 · 2538 次阅读

前言

这段时间在进行 公司 android app 自动化测试项目的构建。

在这一过程中,顺便把多机并发运行的功能也大致开发完毕。

下面简单说一下需求来源,实现思路。

运行效果

两台机器

需求分析

现状

  1. android 系统碎片化(品牌,设备,版本)
  2. 一个 app 需要适配各种机型,各种系统的版本
  3. 新功能发布 QA 需要花大量时间测试设备的兼容性

提升效率

  1. 对部分核心流程进行自动化测试
  2. 多机同时运行测试用例(兼容性测试),多机运行不同测试用例,提升单位时间内测试用例的运行速度

方案设计

技术选择

  1. java 语言 (工程化,可维护性高)
  2. appium(平台自动化测试神器)
  3. docker (初始化运行环境)
  4. jenkins (持续化集成)

具体方案

环境准备
  • 多台移动设备(模拟器),多个 appium server
分配策略
  • 一台移动设备 => 一个 appium server => 一个测试套件
实现方法
  • 测试前在本地启动多个 appium server(按照 port 区分)

appiumserver

  • 获取机器上连接的设备列表(adb devices)

adbdevices

  • 每台设备通过其独立的 udid 绑定到指定的 appium server

appiumconfig

  • 每台设备开启不同的 appium session,并发运行各自的测试用例

capaconfig

架构图

本图摘自-本社区用户terrychow文章

主要代码
  • 根据设备 udid 读取对应的 appium server 配置文件
private static List<AppiumConfig> appiumConfigs = null;
private static ThreadLocal<AppiumConfig> appiumConfigLocal = new ThreadLocal<AppiumConfig>();

/****/
public static AppiumConfig getAvailableServerConfig(){
    if(appiumConfigs == null) {
        appiumConfigs = XmlReader.getAppiumConfigList();
    }

    //获取当前连接的设备
    List<String> udidList = CommandUtil.getUdidList("127.0.0.1");
    //通过设备uid获取对应的appium config
    for (Iterator<AppiumConfig> iterator = appiumConfigs.iterator(); iterator.hasNext();) {
        AppiumConfig config = iterator.next();
        synchronized (config) {
            if (!config.isOccupied()) {
                if (udidList != null && udidList.contains(config.getUdid())) {
                    config.setOccupied(true);
                    LOG.debug("使用设备:ip " + config.getAddress() + " 设备id " + config.getUdid());
                    appiumConfigLocal.set(config);
                    return config;
                }
            }
        }
    }
    return null;
}
  • 根据配置文件进行 appium driver 的初始化
 private static ThreadLocal<RemoteWebDriver> remoteWebDriverThreadLocal = new ThreadLocal<>();

 public static void initDriver(Configuration conf) {
         AppiumConfig appiumConfig = AppiumConfigUtil.getAppiumConfig();
         if(appiumConfig == null){
             appiumConfig = AppiumConfigUtil.getAvailableServerConfig();
         }
         //通过 uid 获取对应 desired capability
        CapabilityConfig capabilityConfig = AppiumConfigUtil.getCapabilityConfig(appiumConfig.getUdid());
        RemoteWebDriver driver = AndroidDevice.getDriver(appiumConfig, capabilityConfig);
        remoteWebDriverThreadLocal.set(driver);
} 
  • 测试用例代码初始化测试驱动对象

    @Override
    @BeforeSuite
    public void onStart() {
        LOG.info("单个套件测试开始,初始化appium driver");
        Configuration conf = new Configuration();
        DriverManager.initDriver(conf);
    
    }
    
    @Override
    @BeforeClass
    public void onBeforeClass() {
        androidDriver = (AndroidDriver<WebElement>) DriverManager.getDriver();
        androidOperateBase = new AndroidOperateBase(androidDriver);
    }
    

注意

  • 在创建 appium session 的时候,需要发送 desired capability 参数,其中 udid 参数才是用来区分不同设备的(之前一直以为是 deviceName)
  • 当测试驱动选择为 uiautomator2 时,需要在 desired capability 中添加 systemPort,用来区分不同设备对应的 uiautomator2.server 所监听的端口, 防止端口冲突
共收到 14 条回复 时间 点赞

那张架构图是观看本社区的用户 terrychow 的文章发现的,架构方面很相似,所以在此引用(为什么 markdown 的图片说明没有显示?)

模拟器做兼容性测试靠谱吗,感觉如果靠谱很多公司就没有必要大量购买真机了

黑山老妖 回复

是的,模拟器确实不太能代表真实机器上的环境,因此我们并没有打算使用虚拟器进行兼容性测试(为了方便演示我暂时使用虚拟机)

既然是 java 代码开发的,那就可以集成到相应的自动化平台上去。
单独运行也可以,但要是能集成到工资的平台上,从 UI 自动化,接口自动化,APP 自动化都能运行,那就 NB 坏了。

秦川风 回复

如你所说,现在是使用我们公司自己改的调度平台,不知道兄弟你知道什么比较好的自动化平台吗?

多机并行足以,还并发……有什么必须要性能说明一下吗

槽神 回复

哈哈,可能是用词不当,我这边的并发指的就是并行吧,作用文章里面我已经说明了(提升测试效率,兼容性测试),所以和性能测试没有太大关系。

槽神 回复

谢谢提醒,已经改正。

xiaomingpapapa 回复

这个群里有个哥们在做一个平台,看着挺高级的。你可以跟他多交流交流,我看看他写的帖子在哪里。
https://testerhome.com/topics/17160
不知道我理解的对不对,我觉得他做的这个平台,加上你的这个手机自动化。如果能糅合到一起,那就是能解决目前很多公司要实现的自动化平台。

秦川风 回复

恩恩,感谢分享。

同一个账户在多个设备之间登录会互相挤掉吧

李鹏 回复

每台设备的登陆账号是不一样的

这样是不是就要多个配置文件了

请问方便开源吗吗?向学习一下 谢谢

需要 登录 後方可回應,如果你還沒有帳號按這裡 注册