Telemetry(项目主页)是 Google 为 Chromium 项目所编写的一套性能测试自动化框架。
从测试架构上以及实际使用中,Telemetry 均表现出极强的易用性和扩展性,本文试图探讨的就是 Telemetry 的框架是如何设计以及为啥这样设计的。
Telemetry 体现的出的易用性以及扩展性
为了体现 Telemetry 的易用性和扩展性,首先我们得先来看看 Telemetry 的用法:
这是 Telemetry 官方文档给出的 Telemetry 的一种基础用法(引用至自 Telemetry: Run Benchmarks Locally):
$ telemetry/run_benchmark --browser=canary smoothness.top_25
以上命令将会让 Telemetry 在名为 canary 的浏览器上执行一段已经预定义好的 Benchmark。而且从所执行的 Benchmark 的命名上我们可以看出,该Benchmark 的性能指标集合为 smoothness,站点集合为 top_25。
-
易用性
由于以上命令已经非常接近业务侧的描述语言,因此使用者无需关注于实现细节,就能很好的使用 Telemetry 完成相关测试。也正是由于这种特性,Telmetry 除了监控 Chromium 和 Chrome 项目的核心性能, 也可以被用作评估 Web 服务的性能。
-
扩展性
Telemetry 已经提供了100+ 项 Benchmark,基本涵盖性能测试的基本需求。但是如果想对其进行扩展也是及其方便的,仅需三步:
- Step 1. 在 page_sets 文件夹中依样画葫芦的新建一个 your_new_pageset.py 文件,添加上你所需的测试的站点。
- Step 2. 在 measurements 文件夹中新建一个 your_new_measurement.py 文件,从预定义好的 metrics 中选择你所需的指标,依样画葫芦的添加进去。
- Step 3. 新增一个 benchmark,指明其 pageset 为 your_new_pageset,其 measurement 为 your_new_measurement 即可。
也即是说在 Telemetry 具备自动检测变更并加载配置的能力。这将大大降低维护工作的成本。
Telemetry 是如何设计的
"事要知其所以然",我们既然知道的 Telemetry 框架具有易用性强且扩张性强的特点,就应该费一点功夫弄清其框架的是如何设计和实现的。
当然框架设计这个命题有点大,因此我们重点从以下几个方向来进行分析:
-
测试对象:
基于Chromium 和 Chrome 内核的所有浏览器,在 浏览页面时 的性能数据。
-
技术手段:
被测对象驱动:以 Chrome DevTools 的 Remote Debugging Protocol 为主,辅助以平台相关的控制命令
性能数据来源:以 Inspector timeline and traces 为主,辅助以平台相关的性能数据 -
测试理念:
Telemetry 最小的可测试对象称为一个基准(Benchmark)。测试所需的配置都被写入到每个基准(Benchmark)中,来保证在不同机器上测试时的一致性。
而一个基准(Benchmark)可以包含有多个测试(Page Test),而这具有由页面集合( Page Set)和测量( Measurement)组成,其中:
- 页面集合( Page Set)定义了测试(Page Test)集合中将会分别测试哪些页面
- 测量( Measurement)定义了在一次测试(Page Test)中将会测试哪些指标(Metrics)
-
测试框架设计方案
下图是笔者根据源码结合自身理解所画 Telemetry 测试框架的架构图:
这个设计方案中有几个明显的特点需要指出:
页面集合( Page Set)和测量( Measurement)是 Telemetry 中最为重要的核心组件。两者几乎完全解耦,因此理论上可以做到任意组合以形成新的基准(Benchmark);
页面集合( Page Set)不仅定义好了页面的URL,而且同时定义了对页面的测试相关操作(Page Action)。因此在测试某些特殊站点(如需要登录账号的站点)时,可以依赖统一的对外封装接口,很方便的进行特殊的内部控制。
测量( Measurement)仅仅决定用哪些指标(Metrics)以及怎么通过这些指标(Metrics)来表达最终的结果。
指标(Metrics)中绝大部分都是由 Telemetry 框架预定义好的。
由于 Telemetry 对测试对象的高度抽象,因此整个测试过程也能高度抽象为一个基类 Page Test,无论页面集合( Page Set)中测试相关操作(Page Action)以及指标(Metrics)的具体实现都可以在 Page Test 所提供的接口中得以实现。
Telemetry 提供了测试所需的各种基础类库,例如用于录制回放的 wpr,用于 Android 设备控制的 devil,用于数据分析处理的 value 等等。
Telemetry 为何要这样设计
正所谓“没有对比就没有伤害”,要想领会 Telmetry 设计的优秀,就先得缕一缕常见的自动化测试框架。
常见的自动化测试基础框架
根据文章《Choosing a test automation framework》(原文、译文)的总结,常见的自动化测试基础框架有如下四种方案:
-
1.测试脚本模块化框架(The Test Script Modularity Framework)
特征:
通过创建独立的,零件化的小脚本,并通过分级的方式将这些小脚本组成更大的脚本,最终来实现一个特定的测试用例。
特点:
- 结构清晰,容易实现
- 在多人团队中,较难实现团队分工
-
2.测试库构架框架(The Test Library Architecture Framework)
特征:
与测试脚本模块化框架的理念相同,区别在于创建的零件并非脚本而是各种库函数以及函数以供上层调用。两者的区别特别像"面向过程"与"面向对象"。
特点:
- 高度模块化,提升了可维护性,在多人团队容易实现分工
- 相对而言代码量较高
-
3.关键字驱动或表驱动测试框架(The Keyword-Driven or Table-Driven Testing Framework)
特征:
该框架的特点是,发明了一套独立于应用程序的"语言"。其中的每个测试项,其测试步骤(或方法)以及测试数据都被写在详细指引里了。
特点:
- 用例可读性强,用例可维护性强
- 实现框架的抽象程度高,难度大
-
4.数据驱动测试框架(The Data-Driven Testing Framework)
特征:
该框架与关键字驱动或表驱动测试框架的区别是,只有测试数据包含在数据文件中。
优缺点:
- 只需要非常少的代码就可以产生大量的测试用例
- 仅适用于测试场景可以高度抽象的情况
Telemetry 架构设计分析
上述四种框架是各有优缺点的基础架构,在实际工程中最常见框架是上述技术的组合,抽取它们的优点,剔除其弱点。而 Telmetry 很明显也就是综合运用上述基础框架模型而形成的。
那么,为什么 Telemetry 要这样设计呢?我们可以简单讨论一下。
Q1: 为啥 Telemetry 没有采用关键字驱动或表驱动测试框架(The Keyword-Driven or Table-Driven Testing Framework)?
A1: 因为 Telemetry 框架提供的是一种 Benchmark 型的测试。因此,需要的是一种可以在不同机器上保持测试一致性的能力,而非灵活定制化的能力。而且实现关键字驱动或表驱动的代价很高,所以没有必要。但是为了保障其易用性,Telemetry 依然在调用命令上下了比较大的功夫,可以让使用者直接从语义上明确当前测试的具体配置。
Q2: Telemetry 是如何使用测试库构架框架(The Test Library Architecture Framework)以及测试脚本模块化框架(The Test Script Modularity Framework)的?
A2: 由于 Telemetry 工程量较大,为了方便多人协作开发,整体上 Telemetry 是采用测试库构架框架(The Test Library Architecture Framework)来设计的。但在具体的模块内部,也有采用测试脚本模块化框架(The Test Script Modularity Framework)。
Q3: 简单分析一下 Telemetry 中数据驱动测试框架(The Data-Driven Testing Framework)的应用?
A3: 虽然前面提到灵活定制化的需求对于 Telemetry 而言并不那么重要,但是在 Page Set 中需要维护大量的站点,并可能存在更新维护的需求。目前,Telemetry 在 Page Set 内部简单实现了一种类似数据驱动测试框架(The Data-Driven Testing Framework)的方式,方便我们从 List 中批量导入被测站点。但笔者认为从方便更新维护的角度考虑,需要针对 Page Set 设计一个可以支持从外部导入数据驱动测试的机制。
我们可以从 Google 身上学到的
由于笔者在工作中也从事浏览器相关的测试工作,因此对比了 Telemetry 与自己开发的测试框架之后,可以总结了如下一些可以从 Telemetry 中学习的要点:
-
高度抽象核心场景并实现充分解耦
Telemetry 在 Page Set 和 Measurement 上的充分解耦是该项目成功的关键,而解耦的基础在于能够抽象出其测试场景是“测试 浏览页面时 的性能数据”。特别是将 Page Action 纳入 Page Set 一并管理,而非将其归属于所谓的测试步骤中(笔者自己写的脚本就是这么做的!囧!),很有借鉴意义。
-
实现上以测试库构架框架(The Test Library Architecture Framework)为主
只要提供的不是 script,而是 framework ,理论上都应遵循这个设计。
-
注重工具的用户体验
本质上来讲,关键字驱动或表驱动测试框架(The Keyword-Driven or Table-Driven Testing Framework)的本质就是为了降低用户使用成本,从而提升用户体验。因此,我们的脚本在使用上一定得做到“看上去就知道是给人用的”。
-
除非测试频率高且变更快(对比 Chromium 的性能测试),不然暂时可以不用考虑关键字驱动或表驱动测试框架(The Keyword-Driven or Table-Driven Testing Framework)
实现成本太高了,这对后期设计其他的框架应该极具参考意义。