Android CTS 測試---自己編譯CTS方法(轉帖)


號外:

http://blog.csdn.net/zjujoe/article/details/5673469 這位大牛太牛了,都記錄下來點滴,感動!

 

 

 

Android CTS 測試---自己編譯CTS方法  

 

 
 
一、 工具篇
准備
Android 環境 Android 代碼、 jdk1.6 git及相應的編譯環境

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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM