Android/测试
测试是一个广泛的主题,包含各种结合不同方法的测试方法,但其本质是试图确保用户的体验令人满意:直观、可靠、响应迅速、安全等。诸如测试驱动开发和行为驱动开发之类的实践在撰写本文时很流行,使用诸如 单元测试 和 集成测试 这样的方法,但更广泛的测试领域包括检查用户是否能够直观地了解如何实现目标,而不会感到沮丧或文化上的误解,以及检查应用程序运行的服务器是否能够承受预期的平均吞吐量、优雅地处理峰值负载、能够抵抗攻击等等。
单元测试是在与(大部分)应用程序的其余部分隔离的情况下测试一个类,并且是测试驱动开发的重要组成部分,其中会编写失败的测试,以便应用程序能够被“调试到存在”。
当正在开发的代码与 Android 无关时,标准的 Java 单元测试技术适用,但当代码与 Android 系统发生交互时,需要进行一定程度的变通(类似于处理遗留代码时所需的操作),以克服包括以下问题在内的困难
- 开发机器上的 android.jar(应用程序构建在其上)在尝试执行其方法时抛出异常
- Android 将这些抛出异常的方法中的许多声明为final,这使得它们无法直接包含在被测代码中
- Android 使用static方法,同样无法直接测试。
关于 单元测试 的部分提供了可以帮助解决这些问题的各种方法;你需要评估它们对你来说是否有效。
以下工具可能也与上述方法一起使用,可以证明很有用
- Robolectric - 提供对 Android 类的单元测试友好模拟,这些模拟在主机 PC 上运行,比在手机或具有非原生架构的模拟器上运行具有更快的编译/执行周期。 [1]
- Hamcrest - 提供有用的和可读的抽象来构建带有有用诊断信息的断言条件
- awaitility - 帮助进行异步测试
- 模拟对象 库提供了构建模拟对象的强大方法
- 依赖注入,它允许你根据接口和映射系统而不是直接通过类来请求对象,因此你可以在不破坏编译代码的情况下替换测试类。这可能会简化你的代码,减少代码阅读量……或者使其更难跟踪到底是谁调用了什么,并且它可能会使启动时间无法接受地变慢。
- RoboGuice
- Spring
- 相关
- Android Annotations - 作为减少样板(进而减少编码错误)的一种手段很有前景,但与测试没有直接关系。它的单元测试部分提到了 Robolectric,这很好。
- Android Binding 不是完全的依赖注入,而是试图使用 MVVM 来分离关注点,可能值得查看。
单元测试是在很大程度上隔离地测试类,而系统测试则检查整个程序集在目标平台上运行时的工作情况,集成测试则检查选定的一组部件是否能够正确地组合在一起——在更容易设置和操作且可以直接访问程序代码的受控条件下。
官方 Android 文档倾向于关注基于 AndroidTestCase 及其子类的测试,评论者经常称它们为“单元测试”。这些测试绝对不是单元测试:因为它们与 Android 系统集成,所以它们至少是集成测试,但由于它们过于嵌入且执行速度太慢,无法作为单元测试,同时它们与代码本身的耦合度过高,无法作为系统测试。(也就是说,在基于英特尔的开发机器上,模拟器启动英特尔 Atom Android 镜像的时间不到 15 秒,而基于 ARM 的镜像则需要 40 秒,这使得它变得更加有用。)
系统测试 对系统进行端到端测试:应用程序将位于设备上,如果使用服务器,它将与服务器通信。它们比单元测试运行速度慢,并且基于以“黑盒”方式通过 UI 驱动应用程序。它们是行为驱动开发的一部分。
由于它们在手机上运行,单元测试的编译/执行周期变成了编译/打包/安装/执行周期,但它们针对的是真实实现,因此不会受到单元测试存根和模拟对象带来的实现不准确性的风险。
以下工具可能很有用
- Robotium - 类似于 Android 上的 Selenium
- Sikuli - 一种屏幕抓取执行系统
- Monkeyrunner - 一种脚本化的 UI 驱动工具
- Android SDK 测试 - 与 Android SDK 一起提供的旧测试系统。
对于随机、长时间运行的测试
- Monkey - 一个随机事件生成器,是 Android SDK 的一部分
一些商业工具在你的设备上运行
- SeeTest、EggPlant(TestPlant)、Apphance
一些商业工具在工具提供商的设备上运行
- DeviceAnywhere
一些应用程序是为浏览器编写的,而不是针对 SDK。对于这些应用程序,Selenium 受支持——尤其是在 ICS 下使用 WebDriver。
有一些商业公司可以将你的应用程序提交给它们,以便在各种设备上进行测试,这样你就不用拥有所有各种平板电脑、手机和支持 Web 的冰箱,人们可能想要在这些设备上运行你的应用程序。好的公司会通过尝试向你出售各种测试方法(除了本书中介绍的方法)来提供隐含的咨询:安全性、性能、可用性和本地化。他们能够提供的功能测试通常会限于黑盒测试,尽管有人可能会开始提供静态检查和架构建议,这并非不可能。
在网上搜索“Android 测试”应该会显示几家此类公司的广告。
测试也是代码,也可能存在错误!诸如变异测试以及条件、分支或行覆盖之类的工具有助于确定你的代码中有多少代码实际上被测试过或仅看起来被测试过。
应用内截图可以作为一种有用的调试工具。 [2]