上一篇 - 使用 Macaca 测试 PC 端应用

I recommend that developers spend 25-50% of their time developing tests - Kent Beck

上周末在云栖 Techday 分享了自动化相关的一些内容,有很多同学来要 PPT,统一回复下,这是会场用的 slide

下面对没提到的一些点也做些总结。前几篇文章都是在简要介绍 Macaca 在各个平台的配置和使用。本篇文章总结下做自动化测试的一些知识和心得,重点介绍如何写好 Macaca 的测试用例。

测试文档我们基本都是遵从IEEE 829标准,常规的测试工程周期如下:

testing

标重的是常被认为容易忽视的环节。

重点考虑的几个方面

可维护性

我曾在这里提过,自动化的本质是软件开发。我们一般会以覆盖率指标来衡量一个产品的用例覆盖程度,如下图,在 UI 黑盒中,我们会使用 TC 通过率来衡量。很多朋友会陷入一个误区认为用例数量多总是好的,侧面反应出产品的覆盖程度很高,完全没必要因为追求数量而写大量用例,反而应该关注用例的有效性。优秀的用例还需要考虑很多方面,比如模块化。

coverage

模块化做的是否高质量,用例架构设计是否合理,直接决定后面的复用性,和整体的维护成本。

Node.js 基于CommonJS,对模块化的支持非常好,每个.js文件都是一个模块,依赖管理,分包都非常方便。如果想引入一个三方包,直接在根目录的package.json中的dependence字段中声明模块名就好了,如果若干模块在一定场景里具有普适性,还可以publish到远端,多用户、多环境共用。

分层考虑

我们提到的模块化不止是代码结构上的模块化,而是从用例的可分层开始考虑,将各层次的测试按照业务生产上的需要,进行合理划分,做到真正意义上的模块化,下图示例一个常规 WEB 产品系统的测试分层。

layer

有了清晰的分层,覆盖测试的思路就会变得清楚很多。覆盖的某些功能常常会依赖其他环境,只要有系统依赖就会有不稳定的因素存在。如果你恰好在使用 Macaca 做产品链路测试或者全功能测试,我们的原则是,只要不是此业务模块产生的问题,而是依赖的其他环境导致的问题,都归为误报。

允许合理 Mock

为了减少误报,需要在用例里做好分支逻辑,比如依赖的环境导致链路无法进行或者进行到异常情况,允许使用 Mock 数据或者跳过某块覆盖,最终体现在报告上。

基于业务扩展

pyramid

基于业务的适配层很重要,尤其是要成规模采用 Macaca 这套方案的时候。我们需要应对自身的业务和产品特性做一层适配,简单到提供一个模块封装,复杂到需要提供服务支持或者配置系统支持,具体实施看应用场景。这里说一个最简单的例子。webdriver-client 源码 就是个适配层的例子,可以发现其中有对 iOS 和 Android 两平台的兼容方法 login

在 iOS 中登录是这个样子:

module.exports = function(username, password) {
  return this
    .waitForElementByXPath('//UIATextField[1]')
    .sendKeys(username)
    .waitForElementByXPath('//UIASecureTextField[1]')
    .sendKeys(password)
    .sleep(1000)
    .sendKeys('\n')
    .waitForElementByName('Login')
    .click()
    .sleep(5000);
};

而 Android 中它可能就是这个样子:

module.exports = function(username, password) {
  return this
    .waitForElementsByClassName('android.widget.EditText', {}, 120000)
    .then(function(els) {
      return els[0];
    })
    .sendKeys(username)
    .sleep(1000)
    .elementsByClassName('android.widget.EditText')
    .then(function(els) {
      return els[1];
    })
    .sendKeys(password)
    .sleep(1000)
    .waitForElementByName('Login')
    .click()
    .sleep(5000);
};

提供了兼容封装或者业务上的适配,即可把模块发布到远端,团队成员之间,各个环境之间公用,当然这是个最简单的例子用于说明。

数据驱动

白盒过程中,我们可以很容易的控制测试流,数据流,覆盖分支情况和可预见的边界情况。自动化的过程可以使用数据驱动的方式,同时Node.js 对于文件处理和系统调用也是非常强大的。Node.js生态几乎支持所有类型的数据库模块,对csv, excel等一些常用的归档格式文件处理也非常棒,例如 node-csv

行为驱动

行为驱动更关注产品的使用预期,从使用行为角度进行用例覆盖,比较适合 UI 层面。在实际业务场景场景中,一定是多方案混合的,另外还有多种手段辅助诊断。** 例如截图对比的方式,针对一些特定场景,就是很好的辅助功能 **。但这并不意味着不纯粹。

复杂度控制

不要追求 100% 的自动化覆盖,某些困难的部分,如果覆盖成本较高,可以考虑弃掉,甚至八二原则取舍。如果因为某些功能的覆盖,导致整体设计过于复杂,最终会造成可预见的大量维护成本,就得不偿失了。

自动化 ≈ 驱动器

自动化最大的意义除了完成人工无法胜任的那部分工作,沉淀和公开化测试过程。它的一个重要意义,我觉得在于可以做其他工作的驱动器,例如,某些特殊需求的场景里,我们还要做必要的专项,如下图。

driver

配合静态扫描

UI 自动化是Continuous Delivery中的一个重要环节。软件研发流程中需要静态扫描的紧密配合。当然,无论是语法 lint,硬编码,初级的 BUG 扫描还是与 PMD 配合工作,Node.js 生态都已经有了很成熟的方案。

cd

某些产品需要 UAT 阶段,图上并没有体现。UAT 在 SIT 后,一般由用户来承担测试角色。

录制是把双刃剑

录制是产生测试用例的一种方式,会在初次完成某测试行为大大降低成本。手工编写用例成本相对高,但是自由度高,可以完成任何需求。

Macaca 会在接下来的版本提供录制工具,方便测试用例的生产。录制也有很大的缺点,一旦产品进入频繁变化期,维护成本将会变得非常高。

再说说 JavaScript

最近,很多用户都会问同一个问题:Macaca 支持多种编程语言吗?

为融合现有的测试体系,Macaca 是基于 Webdriver 标准的,C/S 架构是否支持多语言绑定应该不需要赘述了。

Macaca 的工具和服务端模块都是使用 JavaScript 语言开发的,同时推荐大家实践的语言体系也是 JavaScript。如果对 JS 比较陌生,可以看我提供的两部分内容。JavaScript 基础JavaScript 实战,互联网上也有大量的资料可以轻松学习。

Node.js 是运行 JS 语言的平台,它是跨平台的 WEB 实时应用首选,事件驱动与非阻塞 I/O 模型使其轻量、高效,而且还有强大,一直在膨胀的生态。这也是当初我们为什么选择Node.js,而不是python, ruby, java ...

用例调试

用例调试这里不多说,推荐看这位同学写的文章:编写移动端 Macaca 测试用例 [单步调试]。另外,原 debug-tool 工具不再继续维护。

推荐的测试模块

推荐如下一些模块用在 Macaca 方案里:

测试框架:

断言库:

覆盖率:

数据 Mock:

fakeri18n 支持很友好,曾使用 faker.js + react 开发过 数据 mock 工具

mock

其他的,很容易文档或 Google 到相关内容,这里不赘述了。

Macaca 源码

CI 相关后面会分享。

欢迎讨论,互相学习。

微博: http://weibo.com/xudafeng
Github: https://github.com/xudafeng

下一篇 - 如何获知 Macaca 的最新进展


↙↙↙阅读原文可查看相关链接,并与作者交流