Android CTS 测试---自己编译CTS方法(转帖)

时间:2024-02-22 14:21:43

号外:

http://blog.csdn.net/zjujoe/article/details/5673469 这位大牛太牛了,都记录下来点滴,感动!

 

 

 

Android CTS 测试---自己编译CTS方法  

 

 
 
一、工具篇
准备
Android 环境Android代码、jdk1.6git及相应的编译环境

1 命令行输入

$ sudo apt-get install git-core gnupg sun-java5-jdk flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev valgrind

2.ubuntu10.04 不包含jdk1.6,

sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner"
sudo apt-get update
sudo apt-get install sun-java6-jdk

3.准备Android 源码

要下载其源码,先要安装一个Android的构建工具 repo。repo只是google用Python脚本写的调用git的一个脚本,主要是用来下载、管理Android项目的软件仓库。

$ curl http://android.git.kernel.org/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

然后再建立一个存放源码的目录
$ mkdir ~/android ; cd ~/android

之后使用这个repo工具,来初始化这个源码仓库:

$ repo init -u git://android.git.kernel.org/platform/manifest.git //这是主线上的代码,
也可以用 //$ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake来指定某一版本的source
提交之后,Google会让你提交用户信息什么的,按照要求就OK了。(–b android-2.1_r2)

片刻等待之后,仓库初始化完成。此时,这个仓库只是更新了repo这个构建工具本身,并下载了整个Android源码仓库的一个清单的版本库, 在~/android/.repo下面能够看到这些文件。其中 ~/android/.repo/repo 目录是构建工具的全部代码,基于Python写成,稍后再看。 其次是 ~/android/.repo/manifests/default.xml文件,这个是整个Android源码库的清单文件,之后repo这个工具会 根据这个清单依次下载所有的代码。而~/android/.repo/manifest.git则是这个清单文件的版本库 :) 。

Git有一个有意思的特性,就是可以制定存放版本库版本信息的目录的位置,因而可以将存放版本信息的目录和实际的项目文件放置于不同的目录下,而不 是像以前的cvs或者Subversion一样在每一个目录下都有一个讨厌的.xxx隐藏目录。这也从某种程度上减少了冗余信息。

经过上述步骤之后,可以开始进行源码仓库的下载了,对于repo来说,称之为“同步”——sync。

$ repo sync

下载过程中随时可以终断,中断后重新执行同步即可更新到最新的源码仓库。


切记,切记
这个同步下来的东西是在当前目录下的,而且是一个因此文件夹.repo 用 ls -al 能看到
所以,你一定要自己建立一个目录,比如/home/android,进入这个目录再执行这个命令,要不然就会生成很多多余的文件,你还不知道到底在哪里。
我第一次就是这个,执行了N次,没有看到一个代码,还好,我用find -name 查找,才把他们揪出来了。

 

repo 补充
repo 是一个同步命令,如果输入repo 就是同步所有的代码吧,如果加个参数就是同步某个包的代码。
既然有全部同步的命令,为什么我们要自己那么麻烦去同步其它的呢?因为在同步的过程,经常会出现网络错误。
所以,网上有高人指点说,对于比较大的包,加参数同步,其它的,就不加参数。
在执行初始化好,就是第三步的目录下,我们 cd .repo,就会看到project.list文件,我们可以看到所有project,总共116个。比如 repo sync build、  repo sync external/apache-http等
据个人记忆,好像build 、bionic、dalvik、prebuilt、frameworks/base这几个包比较大,建议单独同步。
(据网上高人说,repo服务器,每个终端最多支持3个线程,也就是我们可以同时开三个repo)
同步过程网络失败太正常了,多试几次就好了,全部下来大概1.3个G,具体时间,看个人网速。

 

4、下载CTS  http://source.android.com/compatibility/cts-intro.html

  在手机或者模拟器上安装CtsDelegatingAccessibilityService.apk
  $sudo ./adb install -r /cts/android-cts/repository/testcases/CtsDelegatingAccessibilityService.apk


手机或者模拟器设置
  Settings->Accessibility->两个选项都选上;
  Settings > Application > Development 三个选项都选上;
  Settings > Sound & Display > Screen Timeout should be set to "Never Timeout";

5.编译篇

#make(这个编译比较长)
#make sdk

代码下载完成后,进入代码目录,这里就以/home/android/为例
里面有一个build/envsetup.sh ,执行.(这个是配置编译环境的,具体细节我目前还不清楚)

$ . build/envsetup.sh          //配置选项,并编译android源码
$ make cts                                 //android源码编译好后,在编译cts

6、编译好cts后生成的文件位置如下
#mydroid/out/host/linux-x86/
在该目录下包含如下测试文件
  • Package CTS: out/host/linux-x86/cts/android-cts.zip
  • cts make file: mydroid/build/core/tasks/cts.mk
  • run cts program: mydroid/out/host/linux-x86/bin/cts
  • test plans: mydroid/out/host/linux-x86/cts/android-cts/repository/plans
  • test packages: mydroid/out/host/linux-x86/cts/android-cts/repository/testcases
  • test results: mydroid/out/host/linux-x86/cts/android-cts/repository/results
  • CTS program settings value: mydroid/cts/tools/utils/host_config.xml
7、连接上Device后,进入如下目录
#mydroid/out/host/linux-x86/bin/
并输入./cts来启动cts测试,效果如下:
Android  CTS  version  2.1_pre_r2  
device(0123456789ABCEDF)  connected
cts_host >
此时输入 help  将会列出cts所有的操作。
cts_host> ls  --plan   //list all  test plan 
cts_host> ls  -p           //list all testcase
cts_host>start  --plan  [plan name]     //test   plan
.............
.............
进入目录 
#mydroid/out/host/linux-x86/cts/android-cts/repository/plans
将会看到有8个测试的基类,它们分别是
 Android.xml     
AppSecurity.xml
CTS.xml
Java.xml
Performance.xml
RefApp.xml
Signature.xml
VM.xml
用UltraEdit打开这些文件后,将会看到所有基类里包含的package 都给出了相应的uri,
cts将根据这些uri去测试每个基类里的package,
 
8、cts_host > start  --plan  Android  
输入上面的命令后,就开始测试 Android API, 其它的类测试命令和这个一致,如下:
cts_host > start  --plan  Android           //test    Android  API
cts_host > start  --plan  CTS               //contains all tests and will run ~21,000 tests on your device  
cts_host > start  --plan  Java             //test   Java  core  libary
。。。。。。。。。
 
9、测试好后,通过输入如下命令来查看测试情况
cts_host > ls  -r
 
10、CTS测试会自动生成相应的测试包,该包位于如下目录:
#mydroid/out/host/linux-x86/cts/android-cts/repository/results
运行测试时,在CTS运行界面能看到测试报告与运行状况。测试完成后可在android-cts/repository/results/下生成详细的测 试报告和一些附加信息,其中用日期和时间命名的文件夹下为所有的测试结果,同时文件夹也会被打成一个对应的.zip包方便提交。用浏览器打开.xml文件 (默认就是,直接双击)就可以查看所用的测试报告了
每个测试包中包含了如下文件;
cts_result.css
cts_result.xsl
logo.gif
newrule-green.png
testResult.xml
该包的测试情况都在 testResult.xml 文件中,通过查看该文件可以知道,那些是和Android兼容的。
 
 
Now lets begin songlixin\'s blog,
 
 
 
 
前言¶

从各种渠道了解到 Android CTS 测试, 是一种类似于 Windows Mobile LTK 的测试。
大体 Google 一下, 发现关于 CTS 的信息非常至少, 只说它有两万多个测试用例。
然后它只对 OHA 成员开发。

本着不抛弃,不放弃的原则,继续 Google...
终于发现了参考1:Cezary Statkiewicz\'s blog。
搞笑的是该 Blog 的前言部分还写着 CTS 不开放。 后面又纠正了 Google 刚刚开放 CTS 信息(见参考2)。

大喜!

先学习¶

原来 Google 定义了一个兼容性规范(Compatibility Definition), 而 CTS 就是用于确保某个测试符合该规范。

从而基于 Android 的应用程序能够在基于同一 API 版本的各种设备上运行。
由于我们使用Android 2.1 (Eclair), 所以从参考2下载到 Android 2.1 的

 Compatibility Definition, 大体阅读一下, 它定义了一些需求:

数据: 必须实现一种无线连接, 速率达到 200Kbit/Sec
Camera: 至少 2M pixels
重力加速: 必须有, 3维, >50Hz
指南针: 必须有, 3纬, >10Hz
GPS: 必须有
内存: 至少 92M (不包括专用内容)
Nand: /data 分区至少 290M
性能: 启动时间: 浏览器 < 1300ms
MMS/SMS < 700ms
AlarmClock < 650ms
第二次启动一个应用的时间不能超过第一次启动时间。
CTS 测试: 必须通过最新的 CTS
升级: 必须有一种办法可以升级全系统。 可以为:
OTA
USB
SD 卡

看来 Android 是在不断往高端方向走。 不过想想也正常,今天的高端就是明天的低端!

Quick Start¶
参考2 的 User Manual 似乎是针对 1.6 的, 其中提到 CTS 是单独下载的一个包。
而参考1 则说从 source code 中编译而来。
先按照参考1简单运行一下。
1) 获取 2.1 代码, 并先做一个基本的编译(不知是否需要)

2) 编译 cts:

    cd ~/mydroid
    . build/evnsetup.sh
    make cts
3)  启动 emulator (或者 device, 不过可能需要按照 User Manual 设置一下)
4) 将 ~/mydroid/out/host/linux-x86/bin 加到路径
5)  adb start-server
6) cts 

 进入 cts 交互环境, 可以敲入 help 看各种命令:cts_host > help
 这里是quick start,所以不详解。
7) 在 shell 下直接以非交互模式运行一下:
$ cts start --plan Signature 
该测试用例比较少,发现两分钟可以运行通过。 像 Android 测试方案就比较耗时间了。

参考¶
1. 某大牛的 Blog 文章
http://bitbar.com/blog/44/using-androids-compatibility-test-suite
2. Android 官方论坛:
http://source.android.com/compatibility/downloads.html
 
继续
 

前言

继续较深入了解 CTS 的细节

先研究一下具体用法

命令行下敲 cts 进入命令行 ,

先看一下帮助

Help 一下

cts_host > help

Usage: command options

Avaiable commands and options:

  Host:

    help: show this message

    exit: exit cts command line

  Plan:

    ls --plan: list available plans

    ls --plan plan_name: list contents of the plan with specified name

    add --plan plan_name: add a new plan with specified name

    add --derivedplan plan_name -s/--session session_id -r/--result result_type: derive a plan from the given session

    rm --plan plan_name/all: remove a plan or all plans from repository

    start --plan test_plan_name: run a test plan

    start --plan test_plan_name -d/--device device_ID: run a test plan using the specified device

    start --plan test_plan_name -t/--test test_name: run a specific test

    start --plan test_plan_name -p/--package java_package_name: run a specific java package

    start --plan test_plan_name -t/--test test_name -d/--device device_ID: run a specific test using the specified device

    start --plan test_plan_name -p/--package java_package_name -d/--device device_ID: run a specific java package using the specified device

  Package:

    ls -p/--package: list available packages

    ls -p/--package package_name: list contents of the package with specified name

    add -p/--package root: add packages from root to repository

    rm -p/--package package_name/all: remove a package or all packages from repository

  Result:

     ls -r/--result: list all result of sessions

    ls -r/--result -s/--session session_id: list detail case result of a specified session

    ls -r/--result [pass/fail/notExecuted/timeout] -s/--session session_id: list detail cases of a specified session by the specified result.

  History:

    history/h: list all commands in command history

    history/h count: list the latest count records in command history

    history/h -e num: run the command designated by \'num\' in command history

  Device:

    ls -d/--device: list available devices

列出所有的 plan

cts_host > ls --plan  

List of plans (8 in total):

CTS

Signature

AppSecurity

Performance

RefApp

Java

VM

Android

 

查看某 plan 的内容

cts_host > ls --plan Android

Packages of plan Android (29 in total):

=================================

android.apidemos.cts

android.accessibilityservice

android.accounts

android.app

android.bluetooth

android.content

android.database

android.dpi

android.dpi2

android.example

android.gesture

android.graphics

android.hardware

android.jni

android.location

android.media

android.net

android.os

android.permission2

android.permission

android.provider

android.speech

android.telephony

android.text

android.util

android.view

android.webkit

android.widget

android.tests.appsecurity

 

添加一个新的 plan

cts_host > add --plan marvell

[Choose package] SignatureTest: select[Y], reject[n], or choose suite in it[m]?  [Y/n/m] Y

Invalid input. Please chose \'y\', \'n\', or \'m\' (default is \'y\')

[Choose package] SignatureTest: select[Y], reject[n], or choose suite in it[m]?  [Y/n/m] y

[Choose package] android.accessibilityservice: select[Y], reject[n], or choose suite in it[m]?  [Y/n/m] y

[Choose package] android.accounts: select[Y], reject[n], or choose suite in it[m]?  [Y/n/m] y

[Choose package] android.apidemos.cts: select[Y], reject[n], or choose suite in it[m]?  [Y/n/m]

[Choose package] android.app: select[Y], reject[n], or choose suite in it[m]?  [Y/n/m] y

。。。。

  [Choose package] android.widget: select[Y], reject[n], or choose suite in it[m]?  [Y/n/m]

 

 

cts_host > ls --plan marvell

The following package(s) contained in plan marvell have been removed:

    SignatureTest

Packages of plan marvell (55 in total):

=================================

android.accessibilityservice

android.accounts

android.apidemos.cts

android.app

。。。

android.widget

 

删除一个 plan

cts_host > rm --plan marvell

 

执行一个 plan

cts_host > start --plan Performance

start test plan Performance

==============================================================

Test package: android.performance2

android.performance2.cts.AppStartup#testStartup........................................................................................................................................................(timeout)

==============================================================

 

CTS_INFO >>> Max ADB operations reached. Restarting ADB...

 

CTS_INFO >>> Restarting device ...

 

CTS_INFO >>> Restart complete.

==============================================================

Test package: android.performance3

android.performance3.cts.AppStartup#testStartup..............(pass)

CTS_INFO >>> Max ADB operations reached. Restarting ADB...

 

CTS_INFO >>> Restarting device ...

 

CTS_INFO >>> Restart complete.

==============================================================

Test package: android.performance4

android.performance4.cts.AppStartup#testStartup.......(pass)

 

CTS_INFO >>> Max ADB operations reached. Restarting ADB...

 

CTS_INFO >>> Restarting device ...

 

CTS_INFO >>> Restart complete.

==============================================================

Test package: android.performance5

android.performance5.cts.AppStartup#testStartup........(fail)

junit.framework.AssertionFailedError: App Took too long to startup: 715 650 at android.performance5.cts.AppStartup.testStartup(AppStartup.java:67)

at android.performance5.cts.AppStartup.testStartup(AppStartup.java:67)

at java.lang.reflect.Method.invokeNative(Native Method)

at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)

at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)

at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)

at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)

at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)

at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

at android.performance5.cts.AppStartup.testStartup(AppStartup.java:67)

at java.lang.reflect.Method.invokeNative(Native Method)

at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)

at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)

at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)

at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)

at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)

at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1404)

at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)

at android.app.ApplicationContext.startActivity(ApplicationContext.java:555)

at android.performance.cts.MultiAppStartupTest.launchActivity(MultiAppStartupTest.java:52)

at android.performance.cts.MultiAppStartupTest.testMultipleApps(MultiAppStartupTest.java:89)

at java.lang.reflect.Method.invokeNative(Native Method)

at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)

at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)

at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)

at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)

at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)

at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

 

Test summary:   pass=2   fail=2   timeOut=1   notExecuted=0   Total=5

Time: 635.927s

 

查看有多少个包

cts_host > ls -p

Available packages (56 in total):

android.util

android.hardware

。。。

android.core.tests.luni.net

android.jni

android.core.vm-tests

 

查看某个包

cts_host > ls -p android.net

Test suites (3 in total):

android.net.cts

android.net.wifi.cts

android.net.http.cts

 

查看测试结果

cts_host > ls -r

List of all results:

Session        Test result                Start time        End time        Test plan name

        Pass    Fail    Timeout    NotExecuted

1        2    2    1    0        2010.06.01 16:18:03    2010.06.01 16:28:39    Performance

2        1    0    0    0        2010.06.01 16:39:38    2010.06.01 16:41:33    Signature

研究 cts 生成文件

cts 脚本文件位于: ~/mydroid/out/host/linux-x86/bin ,它是一个 100 行不到的脚本,最终执行:

java -Xmx512M

-cp ./../framework/ddmlib.jar:./../framework/junit.jar:./../framework/hosttestlib.jar:./../framework/cts.jar:./cts.jar

-DHOST_CONFIG=./../cts/android-cts/repository/host_config.xml

com.android.cts.TestHost

可见, CTS 的 Java 主程序为: com.android.cts.TestHost ,同时使用了配置文件: host_config.xml. 

 

两个 cts.jar: ./out/host/linux-x86/cts/android-cts/tools/cts.jar ./out/host/linux-x86/framework/cts.jar 相同。

 

  cts 使用的目录则为: ~/mydroid/out/host/linux-x86/cts

文件列表 1

songlixin @zjujoe-desktop:~/mydroid/out/host/linux-x86/cts$ tree -L 3

.

├── all_cts_core_files_stamp

├── all_cts_files_stamp

├── android-cts

│    ├── docs

│    ├── repository

│    │    ├── host_config.xml

│    │    ├── log_2010.06.01_16.02.21_.txt

│    │    ├── log_2010.06.01_16.12.22_.txt

│    │    ├── log_2010.06.01_16.38.30_.txt

│    │    ├── log_2010.06.01_16.59.50_.txt

│    │    ├── plans

│    │    ├── results

│    │    └── testcases

│    └── tools

│        ├── cts.jar

│        ├── hosttestlib.jar

│        ├── junit.jar

│        └── startcts

├── android-cts.zip

└── temp

└── description.xml

 

我们关心的主要是 repository 目录。

 

文件列表 2

songlixin @zjujoe-desktop:~/mydroid/out/host/linux-x86/cts$ tree android-cts/repository/

android-cts/repository/

├── host_config.xml

├── plans

│    ├── Android.xml

│    ├── AppSecurity.xml

│    ├── CTS.xml

│    ├── Java.xml

│    ├── Performance.xml

│    ├── RefApp.xml

│    ├── Signature.xml

│    └── VM.xml

├── results

│    ├── 2010.06.01_16.18.03

│    │    ├── cts_result.css

│    │    ├── cts_result.xsl

│    │    ├── logo.gif

│    │    ├── newrule-green.png

│    │    └── testResult.xml

│    ├── 2010.06.01_16.18.03.zip

│    ├── 2010.06.01_16.39.38

│    │    ├── cts_result.css

│    │    ├── cts_result.xsl

│    │    ├── logo.gif

│    │    ├── newrule-green.png

│    │    └── testResult.xml

│    ├── 2010.06.01_16.39.38.zip

│    ├── cts_result.css

│    ├── cts_result.xsl

│    ├── logo.gif

│    └── newrule-green.png

└── testcases

    ├── android.core.tests.annotation.apk

    ├── android.core.tests.annotation.xml

    ├── android.core.tests.archive.apk

  。。。。。。。。。。。。。。。。。。

    ├── CtsWidgetTestCases.xml

    ├── SignatureTest.apk

    ├── SignatureTest.xml

    └── TestDeviceSetup.apk

 

5 directories, 156 files

 

可见 plans  目录下为以 xml 格式定义的测试方案

     results 目录为 测试结果。

     testcases 目录则为一个个测试用例包

host_config.xml 为配置文件

 

研究 cts 源文件

从根目录开始

Cts 的 source 包位于 android 根目录下:

songlixin @zjujoe-desktop:~/mydroid/cts$ tree -L 2

.

├── Android.mk

├── tests

│    ├── accessibilityservice

│    ├── AndroidManifest.xml

│    ├── Android.mk

│    ├── ApiDemosReferenceTest

│    ├── appsecurity-tests

│    ├── assets

│    ├── config_demo

│    ├── core

│    ├── ProcessTest

│    ├── res

│    ├── SignatureTest

│    ├── src

│    ├── tests

│    └── vm-tests

└── tools

    ├── Android.mk

    ├── annotation-helper

    ├── cts-reference-app-lib

    ├── dasm

    ├── device-setup

    ├── dex-tools

    ├── dx-tests

    ├── host

    ├── signature-tools

    ├── spec-progress

    ├── test-progress

    ├── test-progress-new

    ├── utils

    └── vm-tests

 

根目录下的 make file 非常简单:

 

songlixin @zjujoe-desktop:~/mydroid/cts$ cat Android.mk

include $(call all-subdir-makefiles)

 

看来主要内容在两个子目录下。

 

子目录 1 : tools

根目录下的 Android.mk 与其父目录相同。

各子目录代表不同的工具,比如 dasm 编译后的位置是: ./out/host/linux-x86/bin/dasm

这里就不仔细分析这些工具了。

子目录 2 : tests

看一下根目录下的 Android.mk:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := tests

LOCAL_SRC_FILES := $(call all-java-files-under, src)/

              $(call all-java-files-under, core/runner/src)/

              src/android/app/cts/ISecondary.aidl/

              src/android/os/cts/IEmptyService.aidl

 

LOCAL_JAVA_LIBRARIES := android.test.runner

 

# Resource unit tests use a private locale and some densities

LOCAL_AAPT_FLAGS = -c xx_YY -c cs -c 32dpi -c 240dpi -c 160dpi

 

LOCAL_PACKAGE_NAME := CtsTestStubs

 

include $(BUILD_PACKAGE)

 

# Build the test APK using its own makefile, and any other CTS-related packages

include $(call all-makefiles-under,$(LOCAL_PATH))

 

所有 src 及 core/runner/src 下的 java 文件被编译成:

./out/host/linux-x86/cts/android-cts/repository/testcases/CtsTestStubs.apk

 

剩下的就是很多子目录以及子目录的子目录会被编译成 *.apk

 

Tests 目录下每个子目录包括一个 test suite.

songlixin @zjujoe-desktop:~/mydroid/cts/tests/tests$ tree -L 1

.

├── accessibilityservice

├── accounts

├── Android.mk

。。。

├── webkit

└── widget

 

Core 目录下每个子目录包含一个 test suite, 但是他们的代码在其他地方

songlixin @zjujoe-desktop:~/mydroid/cts/tests/core$ tree -L 2

.

├── Android.mk

├── annotation

│    ├── AndroidManifest.xml

│    └── Android.mk

├── archive

│    ├── AndroidManifest.xml

│    └── Android.mk

。。。

├── text

│    ├── AndroidManifest.xml

│    └── Android.mk

├── xml

│    ├── AndroidManifest.xml

│    └── Android.mk

└── xnet

    ├── AndroidManifest.xml

    └── Android.mk

 

appsecurity-tests/test-apps 目录下每个子目录包括一个 test case. 都特别简单 .

 

songlixin @zjujoe-desktop:~/mydroid/cts/tests/appsecurity-tests/test-apps$ tree -L 1

.

├── Android.mk

├── AppAccessData

├── AppWithData

├── InstrumentationAppDiffCert

├── PermissionDeclareApp

├── SharedUidInstall

├── SharedUidInstallDiffCert

├── SimpleAppInstall

├── SimpleAppInstallDiffCert

├── TargetInstrumentationApp

└── UsePermissionDiffCert

 

总结

Cts 其实就是基于 instrumentation test, Test case 有很多类型,不同的实现方式。 对我们来说,需要:

1 )     能够执行现有的 test case

2 )     能够模仿 api demo test case 写一些比较简单的:

可以参考: http://www.netmite.com/ /

android/mydroid/cupcake/development/pdk/docs/instrumentation_testing.html

 

 继续

 

前言

前面都是研究 CTS 面上的东西, 这两天认真学习了一下 Android Instrumentation Test 的相关内容,深切体会到其强大的功能!( UI 控制,生命周期控制,伪环境对象提供等等), 回过头来,我们再来看看 CTS 的细节内容。

 

和前面的内容区分开,我们从具体测试用例的角度来看。

 

 

首先选择文档中经常提起的 apidemo 作为研究对象。

例子一: apidemo

从 test plan 开始研究

 

~/mydroid/out/host/linux-x86/cts/android-cts/repository/plans$ cat CTS.xml

<?xml version="1.0" encoding="UTF-8"?>

<TestPlan version="1.0">

  <Entry uri="android.apidemos.cts"/>

  <Entry uri="android.accessibilityservice"/>

。。。

  <Entry uri="android.core.vm-tests"/>

  <Entry uri="android.tests.appsecurity"/>

</TestPlan>

 

可见,某个 test plan 只需要包括一个到具体测试用例的 uri 申明即可。

 

该 uri 的定义在 test cases 子目录下:

 

~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$ cat ApiDemosReferenceTest.xml

<?xml version="1.0" encoding="UTF-8"?>

<TestPackage AndroidFramework="Android 1.0" apkToTestName="ApiDemos" appNameSpace="android.apidemos.cts" appPackageName="android.apidemos.cts" jarPath="" name="ApiDemosReferenceTest" packageToTest="com.example.android.apis" referenceAppTest="true" runner="android.test.InstrumentationTestRunner" targetBinaryName="" targetNameSpace="" version="1.0">

  <TestSuite name="android">

    <TestSuite name="apidemos">

      <TestSuite name="cts">

        <TestCase name="ApiDemosTest">

          <Test name="testNumberOfItemsInListView"/>

        </TestCase>

      </TestSuite>

    </TestSuite>

  </TestSuite>

</TestPackage>

 

可见 , CTS 在 Android 的 Instrumentation Test 上又包了一层。该 xml 文件的格式说明没有找到,只能先望文生义了。

 

照字面理解,它要测试 ApiDemo, 测试的代码是 ApiDemoReferenceTest, 使用的 Test runner 是:android.test.InstrumentationTestRunner. ( 其它的 test runner 还有: android.test.InstrumentationCtsTestRunner, android.test.InstrumentationCoreTestRunner)

 

该 Test 一共只有一个 test:   testNumberOfItemsInListView

 

以下是相关文件:

songlixin@zjujoe-desktop:~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$ ls -l ApiDemo*

-rw-r--r-- 1 songlixin songlixin 2106161 2010-06-16 09:38 ApiDemos.apk

-rw-r--r-- 1 songlixin songlixin    5526 2010-06-16 09:38 ApiDemosReferenceTest.apk

-rw-r--r-- 1 songlixin songlixin     657 2010-06-16 09:38 ApiDemosReferenceTest.xml

 

现在看看这些位于 out 目录下的文件是如何生成的。

 

再看源码树

根据参考,   要在 cts 中添加一个 test package, 必须将其加入: build/core/tasks/cts.mk.

 

查看一下,果然 , 其中包含:

    ApiDemos /

ApiDemosReferenceTest /

 

ApiDemos 位于:

~/mydroid/development/samples/ApiDemos$ tree -L 2

.

├── AndroidManifest.xml

├── Android.mk

├── assets

│    ├── fonts

│    └── read_asset.txt

├── _index.html

├── res

│    ├── anim

│    ├── drawable

。。。

│    ├── layout

│    ├── menu

│    ├── raw

│    ├── values

。。。

│    └── xml

├── src

│    └── com

└── tests

    ├── AndroidManifest.xml

    ├── Android.mk

    ├── build.properties

    └── src

 

其中, make file 中包含 tests tag:

LOCAL_MODULE_TAGS := samples tests

 

ApiDemosReferenceTest 位于:

~/mydroid/cts/tests/ApiDemosReferenceTest$ tree

.

├── AndroidManifest.xml

├── Android.mk

└── src

    └── android

        └── apidemos

            └── cts

                ├── AllTests.java

                └── ApiDemosTest.java

 

其 make file  没有包含 tests tag, 但是父目录的 Android.mk 中包含了。并且它使用所有子目录的源码。

两个疑问

1)   ApiDemosReferenceTest.xml 是从哪里来的?

猜测: 从 /mydroid/cts/tests/ApiDemosReferenceTest 生成

2)   ApiDemosReferenceTest 中提供了两个 testcase, 而 ApiDemosReferenceTest.xml 只用了一个?

 

从代码上看, ~/mydroid/cts/tools/utilsbuildCts.py  是用来生成 test description 以及 test plan 的。它在~/mydroid/build/core/tasks/cts.mk 中被调用。

 

例子二: CtsExample

CTS test plan 中有:

<Entry uri="android.example"/>

 

这对应:

~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$ ls -l CtsExampleTestCases.*

-rw-r--r-- 1 songlixin songlixin 3294 2010-06-16 10:58 CtsExampleTestCases.apk

-rw-r--r-- 1 songlixin songlixin 1257 2010-06-16 10:59 CtsExampleTestCases.xml

 

看它的 xml 文件:

<?xml version="1.0" encoding="UTF-8"?><TestPackage AndroidFramework="Android 1.0" appNameSpace="com.android.cts.example" appPackageName="android.example " name="CtsExampleTestCases" runner="android.test.InstrumentationTestRunner" version="1.0">

    <TestSuite name="android">

        <TestSuite name="example">

            <TestSuite name="cts">

                 <TestCase name="ExampleTest">

                    <Test name="testBlort">

                        <Description>                            Test {@link Example#blort}.                        </Description>

                    </Test>

                 </TestCase>

                <TestCase name="ExampleSecondaryTest">

                    <Test name="testZorch">

                        <Description>                            Test {@link Example#zorch}.                        </Description>

                     </Test>

                </TestCase>

            </TestSuite>

        </TestSuite>

    </TestSuite>

</TestPackage>

 

其中包含了两个 test case.

 

我们再看 build/core/tasks/cts.mk :

CtsExampleTestCases /

 

该 package 位于:

~/mydroid/cts/tests/tests/example$ tree

.

├── AndroidManifest.xml

├── Android.mk

└── src

    └── android

        └── example

            ├── cts

            │    ├── ExampleSecondaryTest.java

            │    └── ExampleTest.java

            └── Example.java

 

该 package 的特殊之处在于它的测试代码以及被测试代码都在同一个包内。

两个 TestCase 都是从 TestCase 继承,因为它不需要更复杂的功能。

 

可以发现, 相比较 ApiDemo 而言,这是一个更典型的 CTS 测试的例子。如果您想写自己的 cts 测试用例,不凡模仿它。更进一步说, cts/tes/tests 下的那些例子更适合我们用来参考。比如: performance 目录下的MultiAppStartupTest, 继承了 InstrumentationTestCase. 也是一个很好的例子。

 

另外,还发现每个例子其包的最后一段总是 cts, 不知是不是硬性要求。这也可以说明 CTS 是基于instrumentation test, 但是又不等同。

 

疑问

AndroidManifest.xml 中定义的 package name 为: com.andoid.cts.example

 

Example 类属于:

package android.example;

public class Example

 

ExampleTest 类属于:

package android.example.cts;

public class ExampleTest extends TestCase

非常奇怪!

 

 

 

单个运行 CTS 测试用例

安装

~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$ adb install CtsPerformanceTestCases.apk

70 KB/s (4518 bytes in 0.062s)

       pkg: /data/local/tmp/CtsPerformanceTestCases.apk

Success

 

查看一下已经安装的 instrumentation

~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$ adb shell pm list instrumentation

instrumentation:com.android.cts.performance/android.test.InstrumentationTestRunner (target=com.android.calculator2)

instrumentation:com.android.example.spinner.test/android.test.InstrumentationTestRunner (target=com.android.example.spinner)

instrumentation:com.example.android.apis/.app.LocalSampleInstrumentation (target=com.example.android.apis)

instrumentation:com.example.helloandroid.test/android.test.InstrumentationTestRunner (target=com.example.helloandroid)

 

运行(失败)

:~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$ adb shell am instrument -w -r com.android.cts.performance/android.test.InstrumentationTestRunner

INSTRUMENTATION_STATUS: id=InstrumentationTestRunner

INSTRUMENTATION_STATUS: current=1

INSTRUMENTATION_STATUS: class="android".performance.cts.MultiAppStartupTest

INSTRUMENTATION_STATUS: stream=

android.performance.cts.MultiAppStartupTest:

INSTRUMENTATION_STATUS: numtests=1

INSTRUMENTATION_STATUS: test=testMultipleApps

INSTRUMENTATION_STATUS_CODE: 1

INSTRUMENTATION_STATUS: id=InstrumentationTestRunner

INSTRUMENTATION_STATUS: current=1

INSTRUMENTATION_STATUS: class="android".performance.cts.MultiAppStartupTest

INSTRUMENTATION_STATUS: stream=

Error in testMultipleApps:

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.android.calendar/com.android.calendar.LaunchActivity}; have you declared this activity in your AndroidManifest.xml?

       at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1404)

       at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)

       at android.app.ApplicationContext.startActivity(ApplicationContext.java:555)

       at android.performance.cts.MultiAppStartupTest.launchActivity(MultiAppStartupTest.java:52)

       at android.performance.cts.MultiAppStartupTest.testMultipleApps(MultiAppStartupTest.java:89)

       at java.lang.reflect.Method.invokeNative(Native Method)

       at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)

       at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)

       at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)

       at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)

       at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)

       at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

 

INSTRUMENTATION_STATUS: numtests=1

INSTRUMENTATION_STATUS: stack=android.content.ActivityNotFoundException: Unable to find explicit activity class {com.android.calendar/com.android.calendar.LaunchActivity}; have you declared this activity in your AndroidManifest.xml?

       at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1404)

       at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)

       at android.app.ApplicationContext.startActivity(ApplicationContext.java:555)

       at android.performance.cts.MultiAppStartupTest.launchActivity(MultiAppStartupTest.java:52)

       at android.performance.cts.MultiAppStartupTest.testMultipleApps(MultiAppStartupTest.java:89)

       at java.lang.reflect.Method.invokeNative(Native Method)

       at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)

       at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)

       at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)

       at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)

       at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)

       at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

 

INSTRUMENTATION_STATUS: test=testMultipleApps

INSTRUMENTATION_STATUS_CODE: -1

INSTRUMENTATION_RESULT: stream=

Test results for InstrumentationTestRunner=.E

Time: 6.729

 

FAILURES!!!

Tests run: 1,  Failures: 0,  Errors: 1

 

 

INSTRUMENTATION_CODE: -1

songlixin@zjujoe-desktop:~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$

修改

出错信息说是找不到:calendar

 

修改代码,使其不启动 calendar:

        //launchActivity("com.android.calendar", "LaunchActivity", true);

        //Thread.sleep(ACTIVITY_STARTUP_WAIT_TIME);

 

重新编译: make cts

 

重新安装

重新安装用:adb install -r CtsPerformanceTestCases.apk

 

运行(成功)

~/mydroid/out/host/linux-x86/cts/android-cts/repository/testcases$

adb shell am instrument -w -r com.android.cts.performance/android.test.InstrumentationTestRunner

INSTRUMENTATION_STATUS: id=InstrumentationTestRunner

INSTRUMENTATION_STATUS: current=1

INSTRUMENTATION_STATUS: class="android".performance.cts.MultiAppStartupTest

INSTRUMENTATION_STATUS: stream=

android.performance.cts.MultiAppStartupTest:

INSTRUMENTATION_STATUS: numtests=1

INSTRUMENTATION_STATUS: test=testMultipleApps

INSTRUMENTATION_STATUS_CODE: 1

INSTRUMENTATION_STATUS: id=InstrumentationTestRunner

INSTRUMENTATION_STATUS: current=1

INSTRUMENTATION_STATUS: class="android".performance.cts.MultiAppStartupTest

INSTRUMENTATION_STATUS: stream=.

INSTRUMENTATION_STATUS: numtests=1

INSTRUMENTATION_STATUS: test=testMultipleApps

INSTRUMENTATION_STATUS_CODE: 0

INSTRUMENTATION_RESULT: stream=

Test results for InstrumentationTestRunner=.

Time: 7.389

 

OK (1 test)

 

总结

至此,我们大体知道如何运行 cts, 配置 cts, 扩充 cts, 下一步就看具体实践了!

参考链接里有如何添加一个 cts 测试、修改 test plan 的信息,所以本文就没有重复。

参考

Android CTS (Compatibility Test Suite) introduction

http://androidboss.com/android-cts-compatibility-test-suite-introduction-2/