当启动插桩测试时,系统会重启其目标软件包,并且会注入和启动插桩代码以执行测试。一种例外情况是,这里的目标软件包不能是 Android 应用框架本身,即软件包 android,因为这样做会导致出现一种矛盾情况:需要重启 Android 框架,而正是该框架支持系统功能,包括插桩本身。

这意味着,插桩测试无法将本身注入到 Android 框架(也称为系统服务器)以执行测试。为了测试 Android 框架,测试代码只能调用公共 API Surface,或者通过平台源代码树中可用的 Android 接口定义语言 (AIDL) 公开的 API Surface。对于此类测试,针对任何特定软件包都没有意义。因此,按照惯例会将此类插桩声明为针对其自己的测试应用软件包,如其自己的 AndroidManifest.xml 中的 标记所定义。

根据要求,此类测试应用软件包还可以:

捆绑测试所需的 Activity。

与系统共享用户 ID。

使用平台密钥进行签名。

根据框架源代码而不是公共 SDK 进行编译。

此类插桩测试有时称为自插桩。以下是平台源代码中自插桩测试的一些示例:

本文介绍的示例是编写新的插桩测试,其中目标软件包设置为其自己的测试应用软件包。本指南使用以下测试作为示例:

建议您先浏览代码以获得粗略的印象,然后再继续。

确定源代码所在的位置

通常,您的团队已有既定的放置模式,在既定的位置检入代码,并且在既定的位置添加测试。大多数团队拥有单个 git 代码库,或与其他团队共享一个代码库,但有一个包含组件源代码的专用子目录。

假设组件源代码的根位置是在

root>,大多数组件在该位置下具有 src 和 tests 文件夹,以及一些其他文件(如 Android.mk,或拆分为额外的 .mk 文件)、清单文件 AndroidManifest.xml,以及测试配置文件“AndroidTest.xml”。

由于您要添加全新的测试,因此或许需要在组件 src 旁边创建 tests 目录,并为其填充内容。

在某些情况下,您的团队可能会在 tests 下设置更深的目录结构,因为需要将不同的测试套件打包到单独的 apk 中。在这种情况下,您需要在 tests 下创建一个新的子目录。

不管是什么样的结构,您最终都需要在 tests 目录或新建子目录中添加文件,并且文件应类似于示例 gerrit 更改中的 instrumentation 目录中的文件。下面几部分将进一步详细说明各个文件。

清单文件

就像常规应用一样,每个插桩测试模块都需要一个清单文件。如果您将该文件命名为 AndroidManifest.xml 并在 Android.mk 旁边为测试 tmodule 提供该文件,则 BUILD_PACKAGE 核心 makefile 将自动包含该文件。

在继续深入阅读以下内容之前,强烈建议您先查阅应用清单概览。

为方便起见,下面附上快照:

package="android.test.example.helloworld"

android:targetPackage="android.test.example.helloworld"

android:label="Hello World Test"/>

关于清单文件的一些说明:

package="android.test.example.helloworld"

package 属性是应用软件包名称:它是 Android 应用框架用来标识应用(在此上下文中即您的测试应用)的唯一标识符。系统中的每个用户只能安装一个采用该软件包名称的应用。

此外,此 package 属性与 ComponentName#getPackageName() 返回的属性相同,而且也与用来通过 adb shell 与各种 pm 子命令进行交互的属性相同。

另请注意,虽然该软件包名称通常与 Java 软件包名称的样式相同,但是实际上两者之间没有什么关系。换句话说,您的应用(或测试)软件包可能包含具有任何软件包名称的类,但另一方面,您可以选择保持简洁性,使应用或测试中的顶级 Java 软件包名称与应用软件包名称完全相同。

android:sharedUserId="android.uid.system"

此代码声明在安装时,应该为此 apk 授予与核心平台相同的用户 ID,即运行时身份。请注意,这取决于是否使用与核心平台相同的证书为 apk 签名(请参阅上一部分中的 LOCAL_CERTIFICATE),不过它们是不同的概念:

某些权限或 API 受签名保护,这需要相同的签名证书

某些权限或 API 需要调用者的 system 用户身份,如果调用软件包与核心平台本身不同,则需要该软件包与 system 共享用户 ID

所有插桩测试都必须采用此设置,因为相关的类打包在一个单独的框架 jar 库文件中,因此在应用框架调用测试软件包时,需要额外的类路径条目。

android:targetPackage="android.test.example.helloworld"

您可能已经注意到,上述代码声明的 targetPackage 与此文件的 manifest 标记中声明的 package 属性相同。如测试基础知识中所述,此类插桩测试通常用于测试框架 API,所以除了它们本身之外,拥有特定的目标应用软件包并不是很有意义。

简单配置文件

每个新的测试模块都必须具有配置文件,以使用模块元数据、编译时依赖项和打包指令来指引编译系统。在大多数情况下,基于 Soong 的 Blueprint 文件选项就足够了。如需了解详情,请参阅简单的测试配置。

复杂配置文件

重要提示:只有 CTS 测试或需要特殊设置(如停用蓝牙或收集示例数据)的测试需要遵循本部分中的说明。其他所有用例均可通过简单的测试配置来涵盖。如需了解适用于本部分的更多详细信息,请参阅复杂的测试配置。

对于这些更复杂的用例,您还需要为 Android 的自动化测试框架 Trade Federation 编写测试配置文件。

为方便起见,下面附上快照:

关于测试配置文件的一些说明:

上述代码告知 Trade Federation 使用指定的 target_preparer 将 HelloWorldTests.apk 安装到目标设备上。Trade Federation 中有许多目标准备器可供开发者使用,这些目标准备器可用于确保在测试执行之前正确地设置设备。

上述代码指定要用于执行测试的 Trade Federation 测试类,并传入设备上要执行的软件包,以及测试运行器框架(在本例中为 JUnit)。

如需了解详情,请参阅测试模块配置。

JUnit4 功能

虽然测试模式通常特定于组件团队,但有一些普遍有用的使用模式。

@RunWith(JUnit4.class)

public class HelloWorldTest {

JUnit4 的一个显著区别是,不再需要从通用测试基类继承测试,而是在普通 Java 类中编写测试并使用注解来指示某些测试设置和约束。在本例中,我们指示此类应作为 JUnit4 测试运行。

@BeforeClass

public static void beforeClass() {

...

@AfterClass

public static void afterClass() {

...

@Before

public void before() {

...

@After

public void after() {

...

@Test

@SmallTest

public void testHelloWorld() {

...

JUnit4 在方法上使用 @Before 和 @After 注解来执行测试前设置和测试后拆解。同样,JUnit4 可以在方法上使用 @BeforeClass 和 @AfterClass 注解,以便在执行测试类中的所有测试之前执行设置,并在执行测试类中的所有测试之后执行拆解。请注意,类作用域的设置和拆解方法必须是静态方法。对于测试方法,与早期版本的 JUnit 不同,它们不再需要让方法名称以 test 开头,而是每种方法都必须带有 @Test 注解。像往常一样,测试方法必须公开、不声明任何返回值、不接受任何参数,并且可能会抛出异常。

重要提示:测试方法本身带有 @Test 注解;请注意,对于要通过 APCT 执行的测试,它们必须带有测试大小注解:在本例中,将 testHelloWorld 方法注解为 @SmallTest。该注解可以在方法作用域或类作用域内应用。

访问 instrumentation

虽然在基本的 Hello World 示例中未涉及,但是有一种相当普遍的情况是,Android 测试需要访问 Instrumentation 实例:这是核心 API 接口,可提供对应用上下文、Activity 生命周期相关测试 API 等内容的访问权限。

因为 JUnit4 测试不再需要通用基类,所以不再需要通过 InstrumentationTestCase#getInstrumentation() 获取 Instrumentation 实例,新的测试运行器会通过 InstrumentationRegistry(用于存储插桩框架创建的上下文和环境设置)管理该实例。

要访问 Instrumentation 类的实例,只需在 InstrumentationRegistry 类上调用静态方法 getInstrumentation():

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

在本地编译和测试

对于最常见的用例,请使用 Atest。

对于需要更繁琐自定义设置的更复杂用例,请遵循插桩说明。

android 插桩工具,自插桩测试示例  |  Android 开源项目  |  Android Open Source Project...相关推荐

  1. 【字节码插桩】AOP 技术 ( “字节码插桩“ 技术简介 | AspectJ 插桩工具 | ASM 插桩工具 )

    文章目录 一." 字节码插桩 " 技术简介 二.AspectJ 插桩工具 三.ASM 插桩工具 一." 字节码插桩 " 技术简介 性能优化 , 插件化 , 热修 ...

  2. 【开源项目----Android OPenGLES渲染YUV视频文件】

    [开源项目----Android OPenGLES渲染YUV视频文件] OpenGLES对YUV渲染相关文章参考

  3. android afw测试,测试设备配置  |  Android 开源项目  |  Android Open Source Project

    Android Enterprise (AE) 自动化测试框架是一个用于验证 Android 设备的企业级兼容性的测试套件.该套件包括配套应用.测试用例.配置文件和一个基于 cts-tradefed ...

  4. Android签名版本,签名版本以供发布  |  Android 开源项目  |  Android Open Source Project...

    Android 操作系统映像在两个地方使用加密签名: 映像中的所有 .apk 文件都必须经过签名.Android 软件包管理器通过下列两种方式使用 .apk 签名:更换应用时,必须使用与旧应用相同的密 ...

  5. android10分区镜像,分区和映像  |  Android 开源项目  |  Android Open Source Project

    分区 Android 设备包含若干个分区,这些分区在启动过程中发挥不同的作用.为了支持 A/B 更新,设备需要为 boot.system.vendor 和 radio 分区分别单独配置一个槽位. bo ...

  6. redhad环境android源码编译,启动流程  |  Android 开源项目  |  Android Open Source Project...

    建议的设备启动流程如下所示: 图 1. 启动时验证流程 适用于 A/B 设备的流程 如果设备使用的是 A/B 系统,则启动流程略有不同.必须先使用启动控件 HAL 将要启动的槽位标记为 SUCCESS ...

  7. android的wifi直连,WLAN 直连  |  Android 开源项目  |  Android Open Source Project

    WLAN 直连功能又称"WLAN 点对点",它允许支持设备直接使用 WLAN 直连协议发现其他设备并与之互连(无需连接到互联网或移动网络).此功能是基于 Wi-Fi 联盟 (WFA ...

  8. 安卓linux输入代码在哪里,输入  |  Android 开源项目  |  Android Open Source Project

    Android 输入子系统名义上由遍历系统多个层的事件管道组成. 输入管道 在最低层,物理输入设备会生成描述状态更改(例如按键按压和轻触接触点)的信号.设备固件以某种方式编码和传输这些信号,例如向系统 ...

  9. Node.js 单元测试:我要写测试 - Mocha - Nodejs开源项目里怎么样写测试、CI和代码测试覆盖率

    -------------------------------------- 单元测试Express/NodeJs 个人理解, 1,如果不是测试http请求的单元测试,用Mocha, Chai等基本够 ...

  10. 一名测试工程师参与开源项目的经历

    一.初识开源 其实很早就想参与开源项目,但是因为个人编码能力.没有时间等等原因,迟迟没有开始.决定开始参与开源是在从坐班工作换到远程工作之后,有了比较多的时间,一次在逛电鸭论坛时,看到了<开源面 ...

最新文章

  1. Open3d 学习计划—12(Jupyter 可视化)
  2. elasticsearch date格式问题
  3. 我也来晒Flex编写的工作流编辑器
  4. jsonp请求url长度过长的替代(ajaxcdr的使用)
  5. LINUX下安装ORACLE,完全搞定
  6. 他35岁,年薪100万,牛逼的人生无需解释
  7. Keras深度学习框架介绍(结束)
  8. windows cmd编辑文本
  9. pytorch实现图像分类代码实例
  10. 蔡先生论道大数据之八: 让他在看小说的时候, 看到喜欢的汽车
  11. Redis6.0为什么引入多线程
  12. 第12章 决策树 学习笔记上
  13. 小甲鱼python二_小甲鱼python第二讲课后习题
  14. 怎样在图片上编辑文字?这几种方法可以进行简单的编辑
  15. linux-centos7解决视频无法看问题(安装Adobe flash player)
  16. 判定重大风险有哪几种_重大危险源判定
  17. 高级事件----笔记
  18. orc识别较慢_提高OCR识别效率的诀窍
  19. 解决“A problem occurred starting process 'command ''D:\AndroidSdk\..\mips64el-linux-android-strip''的问题
  20. python 通过上传excel对数据分割分组导出

热门文章

  1. 沟通CTBS远程接入软件研究
  2. Android Kotlin关于新增本地数据库对象表字段问题
  3. smobiler中实现页面切换_.Net语言Smobiler开发之如何在手机上实现表单设计
  4. 无穷级数(四)函数的幂级数展开
  5. c语言sinx的幂级数展开式,sinx的幂级数展开式问题?
  6. [项目实战篇] Emos在线办公小程序--环境搭建
  7. 嵌入式学习之QT学习----3 制作简单的QT界面(如:QQ登录界面)
  8. 描述性物理海洋学--第四章学习笔记
  9. MyEclipse 不提示jsp代码
  10. dh算法 理论依据_DH算法为什么属于非对称加密算法?