android自动化测试CTS源码分析之一

1, 概述

CTS(Compatibility Test Suite)全名兼容性测试,主要目的就是让Android设备开发商能够开发出兼容性更好的android设备。

本文的CTS源码基于android 5.1,和其他自动化测试指令一样,CTS测试命令也是通过脚本运行的。

CTS源码中的脚本路径: CTS/tools/tradefed-host/etc/ cts-tradefed

Linux环境中也是运行cts-tradefed脚本进行测试。

cts-tradefed脚本最后一行如下,

[html] view plaincopy
  1. java $RDBG_FLAG \
  2. -cp ${JAR_PATH} -DCTS_ROOT=${CTS_ROOT} com.android.cts.tradefed.command.CtsConsole "$@"

由此可见,android系统中测试的入口为CtsConsole.java类的main方法。

2,main方法

main方法的流程图如下,

CtsConsole的main方法如下,

[html] view plaincopy
  1. public static void main(String[] args) throws InterruptedException, ConfigurationException {
  2. Console console = new CtsConsole(); // 构造CtsConsole对象
  3. Console.startConsole(console, args); // 调用父类的startConsole方法
  4. }

CtsConsole继承于Console,而Console继承于Thread类。

startConsole方法如下,

[html] view plaincopy
  1. public static void startConsole(Console console, String[] args)
  2. throws InterruptedException, ConfigurationException
  3. {
  4. // 将命令参数复制到ArrayList中
  5. List<String> nonGlobalArgs = GlobalConfiguration.createGlobalConfiguration(args);
  6. console.setArgs(nonGlobalArgs); // 将命令参数保存在变量mMainArgs中
  7. console.setCommandScheduler(GlobalConfiguration.getInstance().getCommandScheduler());
  8. console.setDaemon(true);
  9. console.start(); // 启动线程 调用run方法
  10. console.awaitScheduler();
  11. }
  12. }

CtsConsole的run方法如下

[html] view plaincopy
  1. @Override
  2. public void run() {
  3. printLine(String.format("Android CTS %s", CtsBuildProvider.CTS_BUILD_VERSION));
  4. super.run();
  5. }

首先看看打印信息的printLine方法,在父类Console中实现。

[html] view plaincopy
  1. protected void printLine(String output)
  2. {
  3. System.out.print(output);
  4. System.out.println();
  5. }

Console的run方法会做一些检查,最后会调用executeCmdRunnable方法。然后回调内部类ArgRunnable的run方法。

2.1 任务添加

Console的run方法会还会调用CommandScheduler的start方法启动线程。

[html] view plaincopy
  1. this.mScheduler.start();
  2. this.mScheduler.await();

ArgRunnable的run方法会调用CommandScheduler的addCommand方法添加任务。

addCommand调用流程图如下

internalAddCommand方法首先调用ConfigurationFactory的createConfigurationFromArgs方法解析配置文件,

然后根据配置文件的信息调用addExecCommandToQueue将执行计划放入到队列中。

[html] view plaincopy
  1. private boolean internalAddCommand(String[] args, long totalExecTime, String cmdFilePath)
  2. throws ConfigurationException
  3. {
  4. assertStarted();
  5. IConfiguration config = getConfigFactory().createConfigurationFromArgs(args);
  6. •••
  7. config.validateOptions();
  8. if (config.getCommandOptions().runOnAllDevices())
  9. {
  10. addCommandForAllDevices(totalExecTime, args, cmdFilePath);
  11. }
  12. else
  13. {
  14. CommandTracker cmdTracker = createCommandTracker(args, cmdFilePath);
  15. cmdTracker.incrementExecTime(totalExecTime);
  16. ExecutableCommand cmdInstance = createExecutableCommand(cmdTracker, config, false);
  17. addExecCommandToQueue(cmdInstance, 0L);
  18. }
  19. return true;
  20. }
  21. return false;
  22. }

addExecCommandToQueue方法如下,

[html] view plaincopy
  1. private synchronized boolean addExecCommandToQueue(final ExecutableCommand cmd, long delayTime)
  2. {
  3. if (isShutdown()) {
  4. return false;
  5. }
  6. if (delayTime > 0L)
  7. {
  8. this.mSleepingCommands.add(cmd);
  9. Runnable delayCommand = new Runnable()
  10. {
  11. public void run()
  12. {
  13. synchronized (CommandScheduler.this)
  14. {
  15. if (CommandScheduler.this.mSleepingCommands.remove(cmd))
  16. {
  17. CommandScheduler.this.mReadyCommands.add(cmd);
  18. CommandScheduler.this.mCommandProcessWait.signalEventReceived();
  19. }
  20. }
  21. }
  22. };
  23. this.mCommandTimer.schedule(delayCommand, delayTime, TimeUnit.MILLISECONDS);
  24. }
  25. else
  26. {
  27. this.mReadyCommands.add(cmd);
  28. this.mCommandProcessWait.signalEventReceived();
  29. }
  30. return true;
  31. }

另外开一个线程利用回调添加任务,添加到mReadyCommands中

[html] view plaincopy
  1. private List<ExecutableCommand> mReadyCommands;

2.2 组件配置

internalCreateConfigurationFromArgs方法如下,

[html] view plaincopy
  1. private IConfiguration internalCreateConfigurationFromArgs(String[] arrayArgs, List<String> optionArgsRef)
  2. throws ConfigurationException
  3. {
  4. if (arrayArgs.length == 0) {
  5. throw new ConfigurationException("Configuration to run was not specified");
  6. }
  7. optionArgsRef.addAll(Arrays.asList(arrayArgs));
  8. String configName = (String)optionArgsRef.remove(0);
  9. ConfigurationDef configDef = getConfigurationDef(configName, false);
  10. return configDef.createConfiguration();
  11. }

该方法中取出第一个参数cts然后传入getConfigurationDef方法中,获取ConfigurationDef对象。

ConfigurationDef根据测试指令配置相关属性,然后保存在变量中

[html] view plaincopy
  1. private final Map<String, List<String>> mObjectClassMap;
  2. private final List<OptionDef> mOptionList;
  3. private final Map<String, Integer> mClassFrequency;
  4. private final String mName;

属性值的定义在Configuration中。

这样属性也配置好了,如果使用脚本执行CTS测试,每个CTS测试任务都会放入队列中,然后取出依次执行,直到所有执行完为止。

android自动化测试CTS源码分析之一

2017年04月15日 22:21:58

阅读数:1409

1, 概述

CTS(Compatibility Test Suite)全名兼容性测试,主要目的就是让Android设备开发商能够开发出兼容性更好的android设备。

本文的CTS源码基于android 5.1,和其他自动化测试指令一样,CTS测试命令也是通过脚本运行的。

CTS源码中的脚本路径: CTS/tools/tradefed-host/etc/ cts-tradefed

Linux环境中也是运行cts-tradefed脚本进行测试。

cts-tradefed脚本最后一行如下,

[html] view plaincopy
  1. java $RDBG_FLAG \
  2. -cp ${JAR_PATH} -DCTS_ROOT=${CTS_ROOT} com.android.cts.tradefed.command.CtsConsole "$@"

由此可见,android系统中测试的入口为CtsConsole.java类的main方法。

2,main方法

main方法的流程图如下,

CtsConsole的main方法如下,

[html] view plaincopy
  1. public static void main(String[] args) throws InterruptedException, ConfigurationException {
  2. Console console = new CtsConsole(); // 构造CtsConsole对象
  3. Console.startConsole(console, args); // 调用父类的startConsole方法
  4. }

CtsConsole继承于Console,而Console继承于Thread类。

startConsole方法如下,

[html] view plaincopy
  1. public static void startConsole(Console console, String[] args)
  2. throws InterruptedException, ConfigurationException
  3. {
  4. // 将命令参数复制到ArrayList中
  5. List<String> nonGlobalArgs = GlobalConfiguration.createGlobalConfiguration(args);
  6. console.setArgs(nonGlobalArgs); // 将命令参数保存在变量mMainArgs中
  7. console.setCommandScheduler(GlobalConfiguration.getInstance().getCommandScheduler());
  8. console.setDaemon(true);
  9. console.start(); // 启动线程 调用run方法
  10. console.awaitScheduler();
  11. }
  12. }

CtsConsole的run方法如下

[html] view plaincopy
  1. @Override
  2. public void run() {
  3. printLine(String.format("Android CTS %s", CtsBuildProvider.CTS_BUILD_VERSION));
  4. super.run();
  5. }

首先看看打印信息的printLine方法,在父类Console中实现。

[html] view plaincopy
  1. protected void printLine(String output)
  2. {
  3. System.out.print(output);
  4. System.out.println();
  5. }

Console的run方法会做一些检查,最后会调用executeCmdRunnable方法。然后回调内部类ArgRunnable的run方法。

2.1 任务添加

Console的run方法会还会调用CommandScheduler的start方法启动线程。

[html] view plaincopy
  1. this.mScheduler.start();
  2. this.mScheduler.await();

ArgRunnable的run方法会调用CommandScheduler的addCommand方法添加任务。

addCommand调用流程图如下

internalAddCommand方法首先调用ConfigurationFactory的createConfigurationFromArgs方法解析配置文件,

然后根据配置文件的信息调用addExecCommandToQueue将执行计划放入到队列中。

[html] view plaincopy
  1. private boolean internalAddCommand(String[] args, long totalExecTime, String cmdFilePath)
  2. throws ConfigurationException
  3. {
  4. assertStarted();
  5. IConfiguration config = getConfigFactory().createConfigurationFromArgs(args);
  6. •••
  7. config.validateOptions();
  8. if (config.getCommandOptions().runOnAllDevices())
  9. {
  10. addCommandForAllDevices(totalExecTime, args, cmdFilePath);
  11. }
  12. else
  13. {
  14. CommandTracker cmdTracker = createCommandTracker(args, cmdFilePath);
  15. cmdTracker.incrementExecTime(totalExecTime);
  16. ExecutableCommand cmdInstance = createExecutableCommand(cmdTracker, config, false);
  17. addExecCommandToQueue(cmdInstance, 0L);
  18. }
  19. return true;
  20. }
  21. return false;
  22. }

addExecCommandToQueue方法如下,

[html] view plaincopy
  1. private synchronized boolean addExecCommandToQueue(final ExecutableCommand cmd, long delayTime)
  2. {
  3. if (isShutdown()) {
  4. return false;
  5. }
  6. if (delayTime > 0L)
  7. {
  8. this.mSleepingCommands.add(cmd);
  9. Runnable delayCommand = new Runnable()
  10. {
  11. public void run()
  12. {
  13. synchronized (CommandScheduler.this)
  14. {
  15. if (CommandScheduler.this.mSleepingCommands.remove(cmd))
  16. {
  17. CommandScheduler.this.mReadyCommands.add(cmd);
  18. CommandScheduler.this.mCommandProcessWait.signalEventReceived();
  19. }
  20. }
  21. }
  22. };
  23. this.mCommandTimer.schedule(delayCommand, delayTime, TimeUnit.MILLISECONDS);
  24. }
  25. else
  26. {
  27. this.mReadyCommands.add(cmd);
  28. this.mCommandProcessWait.signalEventReceived();
  29. }
  30. return true;
  31. }

另外开一个线程利用回调添加任务,添加到mReadyCommands中

[html] view plaincopy
  1. private List<ExecutableCommand> mReadyCommands;

2.2 组件配置

internalCreateConfigurationFromArgs方法如下,

[html] view plaincopy
  1. private IConfiguration internalCreateConfigurationFromArgs(String[] arrayArgs, List<String> optionArgsRef)
  2. throws ConfigurationException
  3. {
  4. if (arrayArgs.length == 0) {
  5. throw new ConfigurationException("Configuration to run was not specified");
  6. }
  7. optionArgsRef.addAll(Arrays.asList(arrayArgs));
  8. String configName = (String)optionArgsRef.remove(0);
  9. ConfigurationDef configDef = getConfigurationDef(configName, false);
  10. return configDef.createConfiguration();
  11. }

该方法中取出第一个参数cts然后传入getConfigurationDef方法中,获取ConfigurationDef对象。

ConfigurationDef根据测试指令配置相关属性,然后保存在变量中

[html] view plaincopy
  1. private final Map<String, List<String>> mObjectClassMap;
  2. private final List<OptionDef> mOptionList;
  3. private final Map<String, Integer> mClassFrequency;
  4. private final String mName;

属性值的定义在Configuration中。

这样属性也配置好了,如果使用脚本执行CTS测试,每个CTS测试任务都会放入队列中,然后取出依次执行,直到所有执行完为止。

CTS(11)---android自动化测试CTS源码分析之一相关推荐

  1. android agps,Android应用开发Android GPS ——AGPS源码分析及配置

    本文将带你了解Android应用开发Android GPS --AGPS源码分析及配置,希望本文对大家学Android有所帮助. " Android Framework GPS --AGPS ...

  2. android gps源码分析,Android编程之Android GPS ——AGPS源码分析及配置

    本文主要介绍了Android编程的Android GPS --AGPS源码分析及配置,通过具体的分析以及源码,向大家展示了这些,希望对大家学习Android编程有所帮助. 1:冷启动指令: locat ...

  3. Android之AsyncTask源码分析(第五篇:execute方法只能执行一次的原因)

    (注意:本文基于API 28的源码分析,API 29上或其他平台的源码略有不同) 前言 当你调用AsyncTask对象的execute()方法时,突然发生崩溃--内心充满不解:java.lang.Il ...

  4. android(cm11)状态栏源码分析(一)

    版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/50216563 (一):写在前面 最近由于工 ...

  5. Android 7.0 源码分析项目一期竣工啦

    从 Android 入行开始,因为工作需求和解决疑难bug的原因陆陆续续的看过一些源码,但都不成系统,从2016年年底开始,在Github上建了一个Android Open Source Projec ...

  6. Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)

    1.先熟悉handler方式实现主线程和子线程互相通信方式,子线程和子线程的通信方式 如果不熟悉或者忘记了,请参考我的这篇博客     Android之用Handler实现主线程和子线程互相通信以及子 ...

  7. Android——RIL 机制源码分析

    Android 电话系统框架介绍 在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP.AP与BP之间有两种通信方式: 1. ...

  8. Android屏幕刷新——源码分析

    Android屏幕刷新原理--源码分析 文章目录 Android屏幕刷新原理--源码分析 概述 VSync信号 三级缓冲 源码分析 消息队列的同步屏障 参考资料 概述 Android系统每16ms(一 ...

  9. Android Doze模式源码分析

    科技的仿生学无处不在,给予我们启发.为了延长电池是使用寿命,google从蛇的冬眠中得到体会,那就是在某种情况下也让手机进入类冬眠的情况,从而引入了今天的主题,Doze模式,Doze中文是打盹儿,打盹 ...

最新文章

  1. mysql自增长2个增加_mysql – 添加第二个自动增量字段并允许重复
  2. python是目前计算机语言的主流吗_即便C++现在是增长最快的语言,为什么它不及Java、Python流行?...
  3. linux 文件系统 代码,Linux文件系统介绍
  4. [蓝桥杯2015决赛]积分之迷-枚举(水题)
  5. TensorFlow 分布式
  6. C++获取指向二维数组的首元素指针
  7. 2d游戏引擎_8年,从2D到3D,我的学习之路
  8. 计算机网络学习笔记(8. 报文交换与分组交换②)
  9. django admin 定制
  10. 加密算法 java
  11. Kaggle竞赛实战系列(一):手写数字识别器(Digit Recognizer)得分99.53%、99.91%和100%
  12. 蓝叠BlueStacks mac(安卓模拟器)中文免费版
  13. 51单片机+DS18B20+LCD1602显示+Proteus仿真
  14. 仅仅CSS就实现了轮播图----利用关键帧动画实现轮播图效果
  15. android如何虚标内存,答疑 | 手机运存明明是6GB,但实际可用才3.5GB?是虚标还是什么?...
  16. 微信登陆失败Error: invalid code
  17. 献给不知道自己该干什么的朋友—值得一看
  18. c语言编程求百位和个位的差,对任意一个键盘输入的3位整数,求出它的个位、十位和百位。 一道c语言题目?...
  19. Android禁止截屏
  20. win2003 启动报错c0000135 this application has failed to start because csrsrv.dll was not found

热门文章

  1. linux下的网桥介绍
  2. 高性能HTTP加速器Varnish(管理维护篇)
  3. 菜鸟学习笔记:Java基础篇7(包装类、时间相关类、文件类、异常处理类)
  4. 【LeetCode】【HOT】226. 翻转二叉树(递归)
  5. Mycat高级进阶---Mycat注解
  6. python3 抽象基类 abc.abstractmethod
  7. 二分查找的平均查找长度详解【转】
  8. 手机页面尺寸设置(二)
  9. 学习 TList 类的实现[6]
  10. python学习笔记(五)字符串函数二