Android Oreo VTS的环境、编译与运行

简介

VTS,即Vendor Test Suit(供应商测试套件)。 它是Project Treble的一部分,从Android Oreo (8.0)正式开始使用(7.0就开始开发)。 与CTS类似,VTS也是自动化测试的一种手段,主要对HAL与Linux Kernel进行。

Project Treble

在Project Treble后,Vendor的内容为独立的一层,与系统的Framework层隔离。 此后,Framework以上为平台提供给应用的接口,由CTS来测试; Framework以下,为HAL与Linux Kernel提供给Framework的接口,由VTS来测试。

环境准备

测试主机,推荐使用64-bit Ubuntu Linux。 此外,还需要具备以下三个基本的系统环境:

其中,ADB可以通过apt安装,也可以安装Android的platform-tools

除了系统环境,还需要准备额外的测试环境。 进行VTS测试的环境准备,大概需要三步:

  1. 安装 Python 开发工具包
  2. 安装协议缓冲区工具(适用于 Python)
  3. 安装 Python 虚拟环境相关工具
sudo apt-get install \
    python-dev \
    python-protobuf \
    protobuf-compiler \
    python-virtualenv \
    python-pip

VTS测试实际的执行位置,是在对应的手机上。 所以,在测试的主机上,需要连接至少一台用来进行测试的手机,并且可以用ADB成功访问。

此外,也可以使用Windows作为测试环境。 除了基本的系统环境以外,其它都可以通过pip来安装。

pip install protobuf compiler virtualenv

以下默认以Linux环境来介绍。

编译VTS

在一台可以编译Android平台的主机上,执行lunch <product>后,可以直接编译出VTS的相关产物。

$ make vts
$ ls out/host/linux-x86/vts/
android-vts  android-vts.zip  android-vts.zip.list

编译完成的产物,是一个目录,以及这个目录的zip打包文件与文件列表。 VTS测试,可以就在当前编译的主机上进行,也可以通过zip文件,传给其它主机进行。 上一节环境准备,是对测试的主机进行准备,而非编译的主机。

执行测试

在编译的主机,编译VTS完成后,可执行环境中就有了vts-tradefed。 在测试的主机,解压zip文件后,tools子目录下有vts-tradefedvts-tradefed-win.bat可以执行。

$ vts-tradefed
> run vts

vts-tradefed是一个Java项目。 类似SQLite、IPython,执行后会得到一个交互式执行环境,可以输入其它命令。 可以输入help,来查询其它命令的用法,比如help runhelp list等。

run vts就是跑默认的VTS测试Plan。 其它的测试Plan,列出如下:

Plan Description
vts For all default VTS tests.
vts-fuzz For all default VTS fuzz tests.
vts-hal For all default VTS HAL (hardware abstraction layer) module tests.
vts-hal-profiling For all default VTS HAL performance profiling tests.
vts-hal-replay For all default VTS HAL replay tests.
vts-kernel For all default VTS kernel tests.
vts-library For all default VTS library tests.
vts-performance For all default VTS performance tests
vts-camera-its For camera ITS (Image Test Suite) tests ported to VTS.
vts-codelab For VTS codelab.
vts-codelab-multi-device For VTS codelab of multi-device testing.
vts-gce For VTS tests which can be run on Google Compute Engine (GCE)
vts-hal-auto For VTS automotive vehicle HAL test.
vts-hal-tv For VTS tv HAL test.
vts-host For VTS host-driven tests.
vts-performance-systrace For VTS performance tests with systrace enabled.
vts-presubmit For VTS pre-submit time tests.
vts-security For VTS security tests.
vts-system For VTS system tests.
vts-vndk for VTS vndk tests.

实际可用的Plan,是会变化的。 可以通过list plans,列出所有实际可用的Plan。

写一个测试模块

这里参考官方文档《Write a VTS Test》,对如何写VTS测试做一个笼统的介绍。

仿照AOSP项目的test/vts/testcases/codelab/hello_world/,可以看到一个Helloworld样例。 其中,仅有四个文件。

其中,Android.mk指定了编译配置; AndroidTest.xml设置了一些配置信息; __init__.py只是作为一个Python模块必要的标记文件,内容可以为空; VtsCodelabHelloWorldTest.py就是测试的主要内容。

Android.mk

include $(CLEAR_VARS)
LOCAL_MODULE := VtsCodelabHelloWorldTest
VTS_CONFIG_SRC_DIR := testcases/codelab/hello_world
include test/vts/tools/build/Android.host_config.mk

VTS测试模块,也是一个Android的编译模块。 除了前后两个如同定式一样的include,中间简单设置了必要的模块名与源码位置这两个编译信息。

由此也可看出,VTS测试模块,可以写在Android平台的任意位置,最好放在被测项目的某子目录。

AndroidTest.xml

<configuration description="Config for VTS CodeLab HelloWorld test case">
    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
        <option name="push-group" value="HostDrivenTest.push" />
    </target_preparer>
    <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer">
    </target_preparer>
    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
        <option name="test-module-name" value="VtsCodelabHelloWorldTest"/>
        <option name="test-case-path" value="vts/testcases/codelab/hello_world/VtsCodelabHelloWorldTest" />
    </test>
</configuration>

这是一个类似于AndroidManifest.xml的文件,用来设置一些运行时的信息。 至于具体这些标签是什么含义、有哪些可选内容、有没有更多可设置项,除了《Write a VTS Test》以外,找不到更多的内容。

VtsCodelabHelloWorldTest.py

import logging

from vts.runners.host import asserts
from vts.runners.host import base_test
from vts.runners.host import const
from vts.runners.host import test_runner
from vts.utils.python.controllers import android_device

class VtsCodelabHelloWorldTest(base_test.BaseTestClass):
    """Two hello world test cases which use the shell driver."""

    def setUpClass(self):
        self.dut = self.registerController(android_device)[0]

    def testEcho1(self):
        """A simple testcase which sends a command."""
        self.dut.shell.InvokeTerminal("my_shell1")  # creates a remote shell instance.
        results = self.dut.shell.my_shell1.Execute("echo hello_world")  # runs a shell command.
        logging.info(str(results[const.STDOUT]))  # prints the stdout
        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello_world")  # checks the stdout
        asserts.assertEqual(results[const.EXIT_CODE][0], 0)  # checks the exit code

    def testEcho2(self):
        """A simple testcase which sends two commands."""
        self.dut.shell.InvokeTerminal("my_shell2")
        my_shell = getattr(self.dut.shell, "my_shell2")
        results = my_shell.Execute(["echo hello", "echo world"])
        logging.info(str(results[const.STDOUT]))
        asserts.assertEqual(len(results[const.STDOUT]), 2)  # check the number of processed commands
        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello")
        asserts.assertEqual(results[const.STDOUT][1].strip(), "world")
        asserts.assertEqual(results[const.EXIT_CODE][0], 0)
        asserts.assertEqual(results[const.EXIT_CODE][1], 0)

if __name__ == "__main__":
    test_runner.main()

用Python来测试C/C++、Java,也是一个有趣的选择。 以上的样例,都是通过ADB来向手机执行命令,判断返回与打印,来做自动化测试。

其中引用的vts.runners.hostvts.utils.python.controllers等,其实都在test/vts/目录中。 这个Git库,本身就是一个Python包。

单独运行模块测试

$ vts-tradefed
> run vts -m VtsCodelabHelloWorldTest

在样例中,VtsCodelabHelloWorldTest出现在三个文件。 执行测试时,应该是指AndroidTest.xml中的那个配置。

    <option name="test-module-name" value="VtsCodelabHelloWorldTest"/>

如果需要查看所有可测试的模块,可以运行run list modules

VTS Dashboard

测试完毕后,会产生很多测试结果。 Google提供了一个Web应用,专门负责展示这些结果。 代码位置,在AOSP项目的test/vts/web/dashboard/目录下。

这是一个Java后端JSP项目,用Maven构建。 主要功能如下:

  1. 通过网络,接收上传的测试信息
  2. 以漂亮的图表方式,展示各VTS测试项的成功率、覆盖率等信息
  3. 信息存储到数据库
  4. 设置邮件提醒,比如某个测试项失败后提醒某某某

可惜的是,运行时需要GAE环境,本质上这就是一个GAE项目。 也就是说,必须跑在Google的GAE中。 和它比起来,什么软文、硬广都弱爆了。

(孤后来研究了一下《在非GAE环境尝试使用VTS Dashboard》,可惜失败了。)

参考


相关笔记