使用 Android studio 分析运行 CTS 用例

summer · 2016年06月30日 · 最后由 CrystalChen1017 回复于 2016年09月07日 · 1636 次阅读
本帖已被设为精华帖!

CTS 的用例其实是个大宝库,是写单元测试的典范,研究和学习这些用例的内容不管是对 Android 系统的研究还是对个人的技术提升都是很有帮助的。但是网络上对于这部分的介绍却很少,都只是讲怎么运行 CTS 用例,没有去深究这些 case 到底测了什么。这里仅抛砖迎玉,我们先从搭建环境开始。

必备材料:
1.Android 源代码一套(没有的同学参考我另外一篇帖子,我在百度盘共享了全套源码)
2.此套源码要完成编译过程(我这里用的是 Android4.4.4 的源码,使用 64 位 ubuntu14.04 发行版编译,安装了必要的依赖后直接编译完成,全程无错,无需修改任何源代码文件)

下面我们以 WIFI 模块的测试用例为例。
WIFI 模块的测试用例在~/cts/tests/tests/net 目录下,我们看下这个目录的结构:

├── AndroidManifest.xml
├── Android.mk
├── jni
│   ├── Android.mk
│   └── NativeDnsJni.c
└── src
    └── android
        └── net
            ├── cts
            │   ├── ConnectivityManagerTest.java
            │   ├── CredentialsTest.java
            │   ├── DhcpInfoTest.java
            │   ├── DnsTest.java
            │   ├── LocalServerSocketTest.java
            │   ├── LocalSocketAddress_NamespaceTest.java
            │   ├── LocalSocketAddressTest.java
            │   ├── LocalSocketTest.java
            │   ├── MailToTest.java
            │   ├── NetworkInfo_DetailedStateTest.java
            │   ├── NetworkInfo_StateTest.java
            │   ├── NetworkInfoTest.java
            │   ├── ProxyTest.java
            │   ├── SSLCertificateSocketFactoryTest.java
            │   ├── TrafficStatsTest.java
            │   ├── Uri_BuilderTest.java
            │   ├── UriTest.java
            │   ├── UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java
            │   ├── UrlQuerySanitizer_ParameterValuePairTest.java
            │   ├── UrlQuerySanitizerTest.java
            │   └── VpnServiceTest.java
            ├── http
            │   └── cts
            │       ├── ApacheHttpClientTest.java
            │       ├── SslCertificate_DNameTest.java
            │       ├── SslCertificateTest.java
            │       └── SslErrorTest.java
            ├── ipv6
            │   └── cts
            │       └── PingTest.java
            ├── rtp
            │   └── cts
            │       ├── AudioCodecTest.java
            │       ├── AudioGroupTest.java
            │       └── AudioStreamTest.java
            └── wifi
                └── cts
                    ├── ConcurrencyTest.java
                    ├── NsdManagerTest.java
                    ├── ScanResultTest.java
                    ├── SupplicantStateTest.java
                    ├── WifiConfigurationTest.java
                    ├── WifiEnterpriseConfigTest.java
                    ├── WifiFeature.java
                    ├── WifiInfoTest.java
                    ├── WifiManagerTest.java
                    └── WifiManager_WifiLockTest.java

把 net 目录单独拷贝一份,开始动手了,可以看到 net 目录下还包含其他如 http、ipv6 等模块的用例,我们只想分析 wifi 模块的,其它不需要,删掉,目录结构变成这样:

├── AndroidManifest.xml
├── Android.mk
└── src
    └── android
        └── net
            └── wifi
                └── cts
                    ├── ConcurrencyTest.java
                    ├── NsdManagerTest.java
                    ├── ScanResultTest.java
                    ├── SupplicantStateTest.java
                    ├── WifiConfigurationTest.java
                    ├── WifiEnterpriseConfigTest.java
                    ├── WifiFeature.java
                    ├── WifiInfoTest.java
                    ├── WifiManagerTest.java
                    └── WifiManager_WifiLockTest.java

我们要导入 Android studio 进行分析,所以要稍微改造下使它像一个 Android 项目,我们在 src 下添加 bin、gen、libs 三个文件夹,最后变成这样:

├── AndroidManifest.xml
├── Android.mk
├── bin
├── gen
├── libs
└── src
    └── android
        └── net
            └── wifi
                └── cts
                    ├── ConcurrencyTest.java
                    ├── NsdManagerTest.java
                    ├── ScanResultTest.java
                    ├── SupplicantStateTest.java
                    ├── WifiConfigurationTest.java
                    ├── WifiEnterpriseConfigTest.java
                    ├── WifiFeature.java
                    ├── WifiInfoTest.java
                    ├── WifiManagerTest.java
                    └── WifiManager_WifiLockTest.java

很眼熟吧,没错,这就是 eclipse 下面的 Android 项目结构,只不过少了几个其他的 assert,res 之类的文件夹而已,但我们不想用 eclipse,而分析这样的代码用 gradle 项目结构又很麻烦,所以下面讲如何把 eclipse 项目原样导入 Android studio。

把 eclipse 项目导入 Android studio:
1.file->open 打开项目

2.打开 module setting

3.设置 project

4.添加 source 文件夹

5.把 gen 文件夹也添加进去

6.点一下 gen 最右边的 P,在弹出的对话框中勾选 For generated sources

7.Dependencies 界面把 SDK 设置为 19

8.新建一个 Android

9.structure 界面把各个文件夹设置正确,源码文件夹中没有 res 和 assets 没有关系,这里不影响

10.Generated Sources 中设置 gen 目录

11.把 4 个依赖的 jar 包拷贝到源码 libs 目录下,然后在 Libraries 中添加依赖的 jar 包,WIFI 模块一共依赖 4 个 jar 包,这里添加 3 个

说明:
3 个 classes 开头的 jar 包都在编译完成的 out 文件夹下,这里手动改了名字而已
classes-cts.jar 对应~/out/target/common/obj/JAVA_LIBRARIES/ctstestrunner_intermediates/classes.jar
classes-deviceutil.jar 对应~/out/target/common/obj/JAVA_LIBRARIES/ctsdeviceutil_intermediates/classes.jar
classes-framework.jar 对应~/out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes.jar
junit-4.10.jar 网上随便能下载到

12.在 SDKs 中修改 Build target 为 19,并且把 classes-framework.jar 添加进来,且一定要在 android.jar 的前面,这是因为 framework.jar 中有一些系统的隐藏方法,所以要放在公用 API android.jar 的前面被调用

13.编辑 Configurations

14.新建一个 Android Tests

15.重命名,并选择 runner 为 CtsTestRunner

16.项目 - 右键 - 开始 RUN RUN RUN

17.测试结束,可以看到我的设备 fail 了一条用例

这样,我们完成了在 Android studio 运行 CTS 用例的过程,在 Android studio 中运行测试用例好处是方便调试,比如随便断点,方便阅读,方便修改,语法纠错 blablablabla……
如果我们想新写一些用例,也可以在外面写好再弄到源码里配置 mk 文件编译。
至于不同的模块,可能依赖的 jar 包不同,但肯定都在~/out/target/common/obj/JAVA_LIBRARIES 下被编译出来了,所以如果有同学调试其他的模块因为依赖报错的时候,可以根据出错信息到这个目录下去找。

共收到 3 条回复 时间 点赞
Monkey 将本帖设为了精华贴 07月01日 10:29

厉害,学习了

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

cts 资料中的一股清流啊,和那些肤浅的文章果然不一样!

4楼 已删除
5楼 已删除

大神,这几个文件在 android6.0 下不是 jar 包,而是 jack 文件了,这要怎么破呢?

classes-cts.jar 对应~/out/target/common/obj/JAVA_LIBRARIES/ctstestrunner_intermediates/classes.jar
classes-deviceutil.jar 对应~/out/target/common/obj/JAVA_LIBRARIES/ctsdeviceutil_intermediates/classes.jar
classes-framework.jar 对应~/out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes.jar

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