> For the complete documentation index, see [llms.txt](https://wenhowe.gitbook.io/test52lesson/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wenhowe.gitbook.io/test52lesson/018.md).

# 18 - 眼前一亮：带你玩转GUI自动化的测试报告

在 GUI 自动化测试系列的文章中，我围绕着 GUI 自动化测试进行了各种讨论：从最原始的 GUI 测试谈起，逐渐引入了脚本与数据的解耦，并谈论了页面对象模型，以及在此基础上的业务流程模型，接着分享了一些 GUI 自动化测试过程中的新技术，最后和你讨论了 GUI 自动化测试的稳定性问题。

今天，我会再和你聊聊 GUI 自动化测试过程中另外一个很实用的部分：GUI 自动化测试报告。

GUI 测试报告是 GUI 自动化测试的重要组成部分，当有任何的测试用例执行失败时，我们首先就会去分析测试报告，希望从中看到测试用例到底是在哪一步出错了，错误发生时被测系统是在哪个页面上，并且前序步骤又是哪些页面等等。

## 早期的基于视频的 GUI 测试报告

为了分析测试用例的执行过程与结果，早期就出现了基于视频的 GUI 测试报告。也就是说，GUI 自动化测试框架会对测试执行整个过程进行屏幕录像并生成视频。

这种基于视频的测试报告可以提供清晰的 GUI 测试执行上下文，看起来也很不错。但是，这种方式主要的问题是： 1. 报告的体积通常都比较大，小的几 MB，大的上百 MB，这对测试报告的管理和实时传输非常不利。 2. 分析测试报告时，往往需要结合测试用例以及服务端的日志信息，视频报告这一点上也有所欠缺。

所以，**理想中的 GUI 测试报告应该是由一系列按时间顺序排列的屏幕截图组成，并且这些截图上可以高亮显示所操作的元素，同时按照执行顺序配有相关操作步骤的详细描述。**

但是，早期的商业 GUI 自动化测试软件也只是具备最基本的顺序截图，并不具备高亮所操作元素的功能，后来商用工具厂商根据用户的实际使用反馈，逐渐完善和改进。

目前，商业的 GUI 自动化测试软件，比如使用最为广泛的 UFT（就是以前的 QTP），已经自带了截图以及高亮显示操作元素功能。也就是说，使用 UFT 执行一个 GUI 自动化测试用例，你无需做任何额外的工作，就能得到一份比较理想的 GUI 测试报告。

## 开源 GUI 测试框架的测试报告实现思路

但是，如果你使用的是开源软件，比如 Selenium WebDriver，那就需要自己去实现截图以及高亮显示操作元素的功能。实现的思路通常是：

> 利用 Selenium WebDriver 的 screenshot 函数在一些特定的时机（比如，页面发生跳转时，在页面上操作某个控件时，或者是测试失败时，等等）完成界面截图功能。

具体到代码实现，通常有两种方式： 1. 扩展 Selenium 原本的操作函数； 2. 在相关的 Hook 操作中调用 screenshot 函数。

下面，我会分别针对这两个实现方式，给出具体的示例，帮你理解并实现这个功能。

**第一，扩展 Selenium 原本的操作函数实现截图以及高亮显示操作元素的功能**

既然 Selenium 原生的 click 操作函数并不具备截图以及高亮显示操作元素的功能，那我们就来实现一个自己 click 函数。

当自己实现的 click 函数被调用时：

* 首先，用 Javascript 代码高亮显示被操作的元素，高亮的实现方式就是利用 JavaScript 在对象的边框上渲染一个 5-8 个像素的边缘；
* 然后，调用 screenshot 函数完成点击前的截图；
* 最后，调用 Selenium 原生的 click 函数完成真正的点击操作。

那么，以后凡是需要调用 click 函数时，都直接调用这个自己封装的 click 函数，直接得到高亮了被操作对象的界面截图。

如图 1 所示，就是用这种方式产生的界面截图，图中依次显示了登录过程中每一个操作的控件，第一张高亮了“Username”的输入框，因为自动化代码会在“Username”框中输入用户名；第二张高亮了“Password”的输入框，因为自动化代码会在“Password”框中输入密码；第三张高亮了”Sign in“按钮，因为自动化代码会去点击这个按钮。

![avatar](https://4013381155-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LeSFxS8IrTgsxBa95A1%2F-LeSJsqv6dOhk-yX1rOQ%2F-LeSK0fLgLgLtQXHI-FF%2F018_001.jpg?generation=1557417720486631\&alt=media)

图1 GUI 界面的时间顺序截图示例

**第二，在相关的 Hook 操作中调用 screenshot 函数实现截图以及高亮显示操作元素的功能**

其实使用 Hook 的方法比较简单和直观，但是你首先要理解什么是 Hook。

Hook 中文的意思是“钩子”，直接通过定义介绍什么是“钩子”会有些难以理解，那么我就通过一个实例来跟你解释一下。

当执行某个函数 F 时，系统会在执行函数 F 前先隐式执行一个空实现的函数，那么当你需要做一些扩展或者拦截时，就可以在这个空实现的函数中加入自定义的操作了。那么这个空实现的函数就是所谓的 Hook 函数。

这样的例子有很多，比如 Java 的 main 函数，系统在执行 main 函数之前会先在后台隐式执行 premain 函数；JUnit 和 TestNG，都有所谓的 BeforeTest 和 AfterTest 方法，这些都是可以在特定步骤的前后插入自定义操作的接口。

说到这里，你可能已经知道要怎么做了：我可以在这些 Hook 函数中添加截图、元素高亮，以及额外的任意操作，比如更多的详细日志输出等等。

另外，我在前面的文章中分享了基于业务流程的脚本封装，你可以再思考一下，如何在 GUI 报告中体现出业务流程的概念，这样的测试报告会具有更好的可读性。

比如，图2所示的 GUI 测试报告就显示了具体的 Flow 名称。这个功能，就是通过 Hook 函数实现的。

具体的实现逻辑也比较简单的，就是在 Flow 开始的第一个 Hook 函数中调用增加报告页的函数，并在这个新增的报告页中输出 Flow 的名字。

![avatar](https://4013381155-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LeSFxS8IrTgsxBa95A1%2F-LeSJsqv6dOhk-yX1rOQ%2F-LeSK0fOwwAiIrrRNEtR%2F018_002.jpg?generation=1557417708892873\&alt=media)

图2 在 GUI 测试报告中体现业务流程

上面所讲的 GUI 测试报告都是针对一个国家的，当面对多个国家站点的 GUI 测试时，事情就会变得更加复杂，你就必须去考虑全球化 GUI 测试报告应该如何设计。

## 全球化 GUI 测试报告的创新设计

所谓全球化测试是指，同一个业务在全球各个国家都有自己网站。比如，一些大型全球化电商企业在很多国家都有自己的站点，那么对这些站点的测试除了要关注基本的功能，以及各个国家特有的功能外，还要去验证界面布局以及翻译在上下文环境中是否合适。

早期的做法是，雇佣当地的测试工程师，由他们手工执行主要的业务场景测试，并验证相关的页面布局，以及翻译内容与上下文中的匹配度。在当地专门雇佣的这些测试工程师，被称为 LQA。

显然，聘请 LQA 的效率非常低，主要原因是：全部测试工作都由 LQA 在项目后期手工执行，执行前还需要对他们进行业务培训；同时，我们需要准备非常详尽的测试用例文档，LQA 也要花很大的精力去截图并完成最终的测试报告。

为了解决这种低效的模式，最好的解决方法就是：利用 GUI 自动化测试工具生成完整的测试执行过程的截图。这样，LQA 就不再需要去手工执行测试用例了，而是直接分析测试报告中业务操作过程中 GUI 界面截图就可以了，然后发现页面布局问题或者是不恰当的翻译问题。

这个方案看起来已经比较完美了，LQA 的工作重点也更清晰了，但这并不是最优的方案。因为这些 LQA 在实际工作中，还会有以下三个比较痛苦的地方： 1. 需要经常在多个国家的测试报告之间来回切换去比较页面布局； 2. 需要频繁切换到美国网站（也就是主站）的报告，去比较翻译内容与上下文的匹配度； 3. 发现缺陷后，还是需要从 GUI 测试报告中复制截图，并用图像软件标注有问题的点，然后才能打开缺陷管理系统递交缺陷报告。

为了解决这三个问题，我建议你建立以下形式的测试报告。这里有一张图片展示了一份包含多国语言比较报告的示例，听音频的用户可以点击文稿查看如图3所示。

![avatar](https://4013381155-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LeSFxS8IrTgsxBa95A1%2F-LeSJsqv6dOhk-yX1rOQ%2F-LeSK0fQ0NsxuUiPdkVU%2F018_003.jpg?generation=1557417715553698\&alt=media)

图3 多国语言比较报告

报告的横向，是一个国家的业务测试顺序截图，比如图中第一行是英国网站的登录业务流程顺序截图，第二行是德国网站的登录业务流程顺序截图。报告的纵向，展示的自然就是同一界面在不同国家的形式了。

整个报告可以用键盘上下左右依次移动。可想而知，这样的 GUI 测试报告设计一定可以大幅提高 LQA 的效率。

同时，由于这个 GUI 测试报告是基于 Web 展现的，所以我们可以在测试报告中直接提供递交缺陷的按钮，一旦发现问题直接递交缺陷，同时还可以把相关截图一起直接递交到缺陷管理系统，这将更大程度地提高整体效率。

那么，怎么才能在技术上实现测试报告和缺陷管理系统的交互呢？其实，现今的缺陷管理系统往往都有对外暴露 API 接口，我们完全可以利用这些 API 接口来实现自己的缺陷递交逻辑。

这种测试报告的形式就是 eBay 在全球化站点测试中采用的方案，目前已经取得了很好地效果，降低了工作量的同时，还大幅度提高了全球化测试的质量。

## 总结

好了，希望上面的测试报告设计方法可以让你有眼前一亮的感觉。接下来，我总结一下今天的主要知识点。

早期基于视频的 GUI 测试报告由于体积较大，而且不能比较方便地和日志适配，所以并不是最好的解决方案。理想的 GUI 测试报告应该是由一系列按时间顺序的屏幕截图组成，并且可以在这些截图上高亮你所操作的元素，同时按照执行时序配有相关操作步骤的详细描述。

商业 GUI 自动化测试框架的 GUI 测试报告已经做得非常成熟，通常不需要做额外的定制或者开发。但是开源 GUI 自动化测试框架的 GUI 测试报告往往需要自己来开发，主要使用了扩展 Selenium 原本的操作函数的方式以及 Hook 函数来实现。

最后，我介绍了 eBay 面对全球化测试过程中 GUI 测试报告的创新设计，希望你也可以借鉴这种方法。

## 思考题

如果自己去开发 GUI 测试报告的功能，你还能想到其他更多实用的功能吗？你又是如何实现这些功能的？
