热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[WeRead团队博客]&微信读书排版引擎自动化测试方案

WeRead团队博客首页归档微信读书排版引擎自动化测试方案发表于2016-08-23|作者:rich|引言在微信读书App中,排版引擎负责解析E
WeRead团队博客

微信读书排版引擎自动化测试方案

引言

在 微信读书 App 中,排版引擎负责解析 EPUB 或 TXT 格式的书籍源文件,将排版后的书籍内容如文字、图像、注解等元素渲染至屏幕上,是最常用、最复杂的组件之一。

而开发同学对排版引擎的日常修改,可能影响了海量书籍的排版结果。对排版引擎代码变更的测试,往往耗时多、难度大、容易漏测。本文介绍了为解决测试的难题,如何逐步将人工测试步骤自动化,最终构建了一套微信读书排版引擎自动化测试流程,以确保微信读书排版引擎的质量。

背景

排版引擎日常修改

为了获得极致的阅读体验,产品同学经常会提出细致的排版需求,交给开发同学修改。而排版引擎的修改,往往牵一发动全身,可能导致书城上万本书籍排版结果受影响。

举个例子,有个需求是增加正文段落的 margin:

日常修改1

再举个极端的例子,有个需求要把章节标题往右移动1个像素:

日常修改2

那么,如何确保微信读书的排版质量?最开始,我们用人工测试的方法来确保质量。

人工测试方法

当开发按需求修改排版引擎、自测后,会把代码提交到 svn,然后交给测试同学进行测试。

测试同学使用持续集成工具编译打包,得到排版引擎修改后的 App 安装包;然后在两台设备安装排版引擎修改前、后两个版本的 App,同时打开需要测试的书籍,翻页,对比,通过肉眼观察排版差异是否符合预期。

人工测试方法比较耗时,需要打开每本书,一页一页地翻页、对比,而且无法覆盖很多书籍,存在漏测的风险。

另外,通过人眼检查两台设备上的排版结果有没有差异,是很困难的任务,一是容易疲惫导致判断失误,二是对细致的排版变更(如第二个例子)很难判断是否符合预期。

为什么需要自动化测试?

前面提到,人工测试费时耗力,且容易漏测。

此外,排版需求的特点是细节多、变更快,且修改影响范围大,全网书籍上万本,无法一一验证。一旦出错,直接影响口碑。这些因素都增加了人工测试的工作量和压力。

除了精细化的排版需求会对排版引擎代码做修改,在日常的维护中,也会重构排版引擎、修改排版引擎相关但不影响排版结果的代码。每次重构、修改后,也会交给测试同学验证此次修改对排版结果没有影响。由于人工测试比较耗时、无法一一验证,每次重构排版引擎代码压力很大,轻易不敢改动。

还有一种情况,是在开发其他需求、修复缺陷时,意外地导致排版结果受影响。这种错误一旦发布到现网,后果很严重。

所以,把人工测试流程自动化十分有必要。自动化以后,可以大大减少人工测试的时间,同时方便开发同学自测。开发同学对排版引擎也可以大胆重构、持续改进代码质量。最终,达到确保排版引擎质量的目的。

如何自动化测试?

首先,我们要分析一下,在人工测试中,主要有哪些步骤?每个步骤是否能自动化?

在人工测试中,对每次变更的测试,有步骤如下:

  1. 需要把变更前、变更后的 App 包安装到两台设备
  2. 打开 App,登录,把要测试的书购买、加入到书架
  3. 打开要测试的书,设置排版偏好,翻页,用眼睛查看屏幕上的排版结果,对比屏幕中的排版结果是否有差异
  4. 如果有差异,根据需求判断差异是否符合预期

其中步骤 1、2 利用自动化测试工具是比较容易完成的。步骤 3 借助算法能够使其自动化,会在后面详细展开。步骤 4 自动化的难度比较大,可能需要借助非常高阶的人工智能完成,我们把这个步骤交给测试和开发同学。

那么,如何完成步骤 3 的自动化,让机器做人类的事情呢?我们把它再细分成三个步骤:

1. 获取排版结果的数据表示

首先,需要找到一种机器能读懂的数据表示,这种数据表示要既能够表示排版的结果、反映代码的修改,也能够通过算法来对比,对比的结果要便于可视化的展示,方便开发、测试同学判断差异是否符合预期。

我们的选择有:

  1. NSAttributedString,是从 EPUB、TXT 处理后得到的中间数据,包括文字和排版样式。这种数据结构比较抽象,没有一种很好的差异计算方法、和差异结果可视化方法。

  2. 阅读器屏幕截图,位图格式,借助各种成熟的数字图像处理算法,容易计算差异

考虑到 2 容易计算差异,可视化输出效果较好,我们选取阅读器屏幕截图作为数据表示。

2. 对比图像差异

选择了图像作为排版结果的数据表示,那么如何对比图像差异呢?

首先,我们要选取图像特征,然后才能对比图片差异。图像的特征,从视觉认知概念上,有低、中、高级特征:

  • 低级特征:如像素域、频率域、ImageHash
  • 中级特征:如 sobel 边缘特征
  • 高级特征:抽象视觉概念,比如从 CNN 算法训练得到的标签,如车、枪、球

这里我们希望每个像素的差异都能检测到,所以选取像灰度化处理过的图像矩阵作为特征。

有了特征后,我们需要定义差异,就是两个灰度图像矩阵的距离函数,如:

  • L0,表示两个灰度图像矩阵之间,不一致的像素点的个数
  • L1,曼哈顿距离或棋盘距离,不一致像素点差值的绝对值之和
  • L2,不一致像素点差值的平方和

我们关心有多少像素点不一致,所以我们这里取 L0距离,即两个图像有多少个像素点不一样,作为差异衡量的指标。

当距离大于10时,我们认为这一页的排版结果有差异,把它可视化输出,给开发或者测试同学作为参考。

3. 可视化输出

检测到差异后,我们把两个图像矩阵灰度化后相减,得到一个新的矩阵,把它归一化得到差异图像,如右图所示:

日常修改2

通过 scheme 生成排版结果

人工测试步骤 2、3 的书籍购买、加入书架、打开书籍、翻页、截图等任务,可以利用 Instrument UI Automation 自动测试脚本来模拟人工点击来完成任务。

但是考虑到 Automation 模拟翻页、截图速度慢,且 UI 变更频繁导致 Automation 脚本后续维护麻烦等问题,所以我们通过提供一个测试 scheme 接口来完成这个任务。

在 App 设置彩蛋的『执行 Scheme 页面』中,输入 scheme 并执行后,App 会在后台对指定书籍购买、加入书架、排版、生成排版结果截图,并把结果保存在本地磁盘。用户也可以选择 AirDrop 到 Mac 上。

运行scheme

scheme 格式如下:

1
2
3
4
5
6
7
8
weread://typeset?books=三体,乔布斯传,失控,1984,乌兰拖拉机简史&indent=1&fOntSize=2&fOnt=2&theme=3&folder=f1223
输出排版结果到目录/Libary/[vid]/[folder]/[bookId].zip
@param books 需要排版的书单
@param indent 0首行不缩进 1首行缩进,默认0
@param fontSize 1,2,3,4,5,6,7 字体大小,默认4
@param font 字体 1系统字体 2 3 4 为对应选项字体,默认1
@param bgcolor 背景颜色 1白 2黄 3绿色 4夜间,默认1
@param folder 输出文件夹名,默认"cropImage"

通过这个 scheme,在真机或者模拟器都可以随时得到排版结果,而且速度比模拟翻页要快10x。

自动化测试流程

下面,将介绍我们完整的排版引擎自动化测试流程。

1 生成排版结果

首先,用户需要确定参数:待生成排版结果的 svn 版本范围 r1~rn、书单、阅读偏好设置(字体、缩进、主题模式)。把这些参数传给脚本batch_scan.py,然后自动化流程开始,脚本会执行以下步骤:

  1. 在指定 svn 版本范围内,找出排版引擎有变更的版本,checkout
  2. 对每个 checkout 的版本,用 xcodebuild 编译项目,安装到模拟器
  3. 通过 Instrument 的 UI Automation 脚本,打开模拟器,运行微信读书App,进入到测试彩蛋页面:执行 scheme,生成排版结果
  4. 把结果从模拟器移动到指定的目录下

生成排版结果

2 生成排版结果差异

得到排版结果后,执行脚本 batch_diff.py,对相近的版本,每本书的每一页通过 diffimg.py 对比,如果有差异,则输出可视化的差异结果。

对比排版结果

3 人工检查差异

自动化流程结束后,我们得到排版结果差异,需要人工去检查差异是否符合预期。

我们以文件夹的形式组织展示差异的可视化结果:版本 r1(修改前)与 r2(修改后),对书籍 book1 排版差异可视化结果,保存在文件夹 diff_result_r1_r2/book1 中。

可视化结果图像中,深色字体是 r1 (修改前)的排版结果,浅色字体是 r2 (修改后)的排版结果。

另外,排版性能变化也纳入了监控。

检查排版差异

自动化测试的优势

自动化流程的建立,使排版引擎的测试时间缩短了 95%,测试期间无需人工干预,对比数据如图:

排版差异

例如,人工测试一本 550页的 《哈利波特与被诅咒的孩子》需要约 20 分钟,而自动化测试脚本扫描、对比差异只需 22 秒(不含编译时间);人工测试 10 本书籍,用时约 3 小时,而自动化测试用时约 4.9 分钟;人工测试 100 本书籍需 33 小时,而自动化测试用时约 50 分钟。

除了大大减少人工测试的时间,开发同学借助自动化测试工具,能大胆重构代码,通过自动化测试来确保重构不影响排版结果,拥抱快速变更的需求。

随着自动化测试覆盖的变更版本、测试的书籍数量越来越多,带来的收益越大。

借助自动化测试流程,对于任何代码修改而导致样本书籍、每一页、每个像素点的排版结果变更,都能够纳入我们的监控,最终达到确保微信读书排版引擎质量的目的。

未来工作

目前,自动化测试工具已经投入使用。未来会持续优化、增加特性,以满足测试、开发同学的需求。

未来工作包括但不限于:

  • 邮件通知:执行脚本得到结果后,如果两个版本之间的排版结果有差异,通过邮件通知相关同学;另外,排版的性能对比结果也可以生成一份报告,通过邮件通报。

  • 运行速度优化:目前对 20 本书生成排版结果,耗时约 10 分钟,对比耗时约 2 分钟。可以进一步优化运行速度,争取覆盖更多样本书籍

  • 支持微信读书安卓版

  • 尝试应用在其他模块:对运行预期结果相对固定、测试代价大的功能模块,可以通过支持测试 scheme,输出运行结果截图,以插件的形式接入这一套自动化测试流程。

总结

本文介绍了微信读书排版引擎的日常修改时,人工测试所面临的问题,以及为什么需要自动化测试的原因。

然后本文分析了人工测试的流程,以及这些流程改造成自动化的可能性。

最后,介绍了我们整套自动化测试流程,以及应用自动化测试以后所来的好处,最终达到确保微信读书排版引擎质量的目的。

SQLite线程模式探讨
基于 UIWebView 的富文本编辑器实践
 
 

T


推荐阅读
  • 通过将常用的外部命令集成到VSCode中,可以提高开发效率。本文介绍如何在VSCode中配置和使用自定义的外部命令,从而简化命令执行过程。 ... [详细]
  • 基于Linux开源VOIP系统LinPhone[四]
    ****************************************************************************************** ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 本文探讨了基于点集估算图像区域的Alpha形状算法在Python中的应用。通过改进传统的Delaunay三角剖分方法,该算法能够生成更加灵活和精确的形状轮廓,避免了单纯使用Delaunay三角剖分时可能出现的过大三角形问题。这种“模糊Delaunay三角剖分”技术不仅提高了形状的准确性,还增强了对复杂图像区域的适应能力。 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 近期在研究逆向工程,因此尝试了一些CTF题目。通过合天网络安全实验室的CTF实战演练平台(http://www.hetianlab.com/CTFrace.html),我对Linux逆向工程的掌握还不够深入,因此暂时跳过了RE300题目。首先从逆向100开始,将文件后缀名修改为.apk进行初步分析。这一过程不仅帮助我熟悉了基本的逆向技巧,还加深了对Android应用结构的理解。 ... [详细]
  • 在机器学习领域,深入探讨了概率论与数理统计的基础知识,特别是这些理论在数据挖掘中的应用。文章重点分析了偏差(Bias)与方差(Variance)之间的平衡问题,强调了方差反映了不同训练模型之间的差异,例如在K折交叉验证中,不同模型之间的性能差异显著。此外,还讨论了如何通过优化模型选择和参数调整来有效控制这一平衡,以提高模型的泛化能力。 ... [详细]
  • 探索聚类分析中的K-Means与DBSCAN算法及其应用
    聚类分析是一种用于解决样本或特征分类问题的统计分析方法,也是数据挖掘领域的重要算法之一。本文主要探讨了K-Means和DBSCAN两种聚类算法的原理及其应用场景。K-Means算法通过迭代优化簇中心来实现数据点的划分,适用于球形分布的数据集;而DBSCAN算法则基于密度进行聚类,能够有效识别任意形状的簇,并且对噪声数据具有较好的鲁棒性。通过对这两种算法的对比分析,本文旨在为实际应用中选择合适的聚类方法提供参考。 ... [详细]
  • 在MySQL中实现时间比较功能的详细解析与应用
    在MySQL中实现时间比较功能的详细解析与应用。本文深入探讨了MySQL中时间比较的实现方法,重点介绍了`UNIX_TIMESTAMP`函数的应用。该函数可以接收一个日期时间参数,也可以不带参数使用,其返回值为Unix时间戳,便于进行时间的精确比较和计算。此外,文章还涵盖了其他相关的时间处理函数和技巧,帮助读者更好地理解和掌握MySQL中的时间操作。 ... [详细]
  • 从2019年AI顶级会议最佳论文,探索深度学习的理论根基与前沿进展 ... [详细]
  • 分布式开源任务调度框架 TBSchedule 深度解析与应用实践
    本文深入解析了分布式开源任务调度框架 TBSchedule 的核心原理与应用场景,并通过实际案例详细介绍了其部署与使用方法。首先,从源码下载开始,详细阐述了 TBSchedule 的安装步骤和配置要点。接着,探讨了该框架在大规模分布式环境中的性能优化策略,以及如何通过灵活的任务调度机制提升系统效率。最后,结合具体实例,展示了 TBSchedule 在实际项目中的应用效果,为开发者提供了宝贵的实践经验。 ... [详细]
author-avatar
归零xinghx_318
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有