
经过将近五个月、60篇文章的学习，相信你已经对软件测试的全貌有了一个大致的理解，而对某一种类型的测试（比如，GUI自动化测试、移动App的自动化测试、性能测试等），也有了更深入的理解。

现在，我从专栏中精心挑选了25个核心知识点，组成了25道测试题目（包含20道选择题，5道问答题）。希望可以帮助你检测一下这段时间的学习成果，以期对这些核心知识的理解可以达到炉火纯青的程度。

如果你刚刚打开这个专栏，可以用这25道题目，找到自己的薄弱点，对症下药；如果你已经学习了一段时间，可以用这25道题目，检测一下学习成果，查漏补缺。

我的建议是：选择题部分，你可以直接进入考试系统作答，系统也会给你自动判分。对于简单题，你可以拿出纸笔，简单写下答案，然后再与文末的答案进行对照。

点击下面按钮进入选择题部分，选择题中有单选题有多选题，系统自动评分（满分为100分）。

[<img src="https://static001.geekbang.org/resource/image/28/a4/28d1be62669b4f3cc01c36466bf811a4.png" alt="">](https://time.geekbang.org/quiz/intro?act_id=77&exam_id=109)

# 问答题

<li>
GUI自动化测试脚本分层设计的最佳实践是怎样的？
</li>
<li>
多个API连续调用的测试用例的难点是什么？你是如何来解决的？
</li>
<li>
单元测试中，桩函数和Mock函数用来解决什么问题，两者又有什么区别？
</li>
<li>
性能压测过程中，当面对大量并发用户调用的时候，服务器端CPU的使用率是高好还是低好？为什么？
</li>
<li>
当需要在尽可能短的时间内完成大量GUI自动化测试用例的执行时，业界主流的解决方案是什么？
</li>

# 答案与解析

1.  GUI自动化测试脚本分层设计的最佳实践是怎样的？

**考点分析：GUI自动化测试脚本的分层设计原理。**

**答案与解析：**

大量GUI自动化测试能够成功的关键，就在于脚本的分层设计。而脚本分层设计的核心思想就是模块化。

首先，我们需要对页面进行抽象，形成页面对象模型。在这样的测试用例中，你看到的都是类似于XXXPage.YYYComponent.ZZZOperation的语句。它们和实际的手工测试可以建立一一对应的关系，用通俗的话语来讲，就是某某页面上的某某元素，执行了某某操作。

接下来，为了使GUI自动化测试脚本更加符合业务场景的描述，同时进一步提高脚本的封装性和可重用性，就需要引入业务流程脚本的概念。这里，业务流程和实际的业务流程也是一一对应的关系。这样，测试用例就可以通过调用业务流程脚本来实现，测试用例本身的可读性以及可维护性也会更好。同样地，业务流程脚本，也是基于页面对象模型实现的。

关于页面对象模型的细节，你可以再回顾下第13篇文章[《效率为王：脚本与数据的解耦 + Page Object模型》](https://time.geekbang.org/column/article/11966)中的相关内容。

而关于业务流程抽象的细节，你可以再回顾下第14篇文章[《更接近业务的抽象：让自动化测试脚本更好地描述业务》](https://time.geekbang.org/column/article/12135)中的相关内容。

2.  多个API连续调用的测试用例设计难点是什么？你是如何解决的？

**考点分析：多个API连续调用时，前后两个API之间的参数传递。**

**答案与解析：**

单个API测试并不难，难的是多个API的连续调用，并且后一个API的参数值使用的是前一个API调用的返回结果，这就要求多个API调用之间可以方便地进行参数传递。一个最典型的场景就是，前一个API调用会返回一个有效的token，后一个API调用需要带着这个token才能调用成功。

为了解决这个问题，一般来讲有三种处理方法：

- 第一种方法是，手工复制前一个API返回结果中的某个值，然后粘贴给后一个API作为输入参数。当然，这是最基本的方法，但是效率太低，而且无法实现自动化。
- 第二种方法是，使用基于代码的API测试框架。由于此时所有的测试逻辑都是通过代码来实现的，因此可以很容易地实现API之间的参数传递。
- 第三种方法是，借助于类似HttpRunner之类的已有API测试框架。此类框架可以通过关键字，很方便地将前一个API的返回值中的某个值传递给下一个API作为输入参数。

关于复杂场景下的API测试，建议你再回顾下第22篇文章[《从0到1：API测试怎么做？常用API测试工具简介》](https://time.geekbang.org/column/article/13421)中的相关内容，以及[《测试专栏特别放送 | 答疑解惑第四期》](https://time.geekbang.org/column/article/64936)中的第一个问题。毕竟，复杂场景的API测试，才是我们业务场景中最常遇到的，也是软件测试工程师面试过程中经常会被问题到的问题。

3.  单元测试中，桩函数和Mock函数主要用来解决什么问题？这两者又有什么区别呢？

**考点分析：理解桩函数和Mock函数的本质区别。**

**答案与解析：**

当被测函数中调用了第三方的函数时，我们一般会采用桩函数或者Mock函数来模拟这些第三方函数，以此来实现被测函数的高代码覆盖率。可以说，桩函数和Mock函数的使用大大方便了单元测试的开展，同时也解决了单元测试的代码耦合性问题。

但是，这两者到底有什么区别呢？

通俗来讲，如果你的测试验证是在被测函数中进行的，那么此时你使用的就是桩函数；而如果你的测试验证是在被模拟的函数中进行的，那么这个被模拟的函数就是Mock函数。

更详细的分析，你可以再回看下第3篇文章[《什么是单元测试？如何做好单元测试？》](https://time.geekbang.org/column/article/10275)中的相关内容。

4.  性能压测过程中，当面对大量并发用户调用的时候，服务器端CPU的使用率是高好还是低好？为什么？

**考点分析：理解性能测试指标解读的复杂性，必须要全盘考虑多个指标间的相互关联和制约。**

**答案与解析：**

这个问题的答案，一定会有坚持不同意见的两派人。

- 一部分人认为，CPU使用率当然是越低越好。这说明后端代码实现得很高效，只占用很少的计算资源就能实现较高的并发。并发情况下，越低的CPU占用率，说明系统可以继续承载越多的并发负载。
- 而另一部分人则认为，CPU的使用率是越高越好。这说明系统的计算资源被充分利用了起来。

你同意哪个观点呢？

其实，这个问题本身就是个伪命题，单单通过题干中的信息是不足以给出孰好孰坏的结论的。这里的关键是，随着并发用户数的上升，事务的响应时间是如何变化的。

如果随着并发用户数的增加，事务的响应时间也呈线性增长，但CPU的使用率一直上不去，这就是典型的CPU资源没有被充分利用的现象。此时，你就需要去进一步诊断为什么CPU资源不能在并发场景下被充分利用。

而如果随着并发用户数的增加，事务的响应时间能基本保持稳定，同时CPU的使用率会随着并发用户数的增加呈线性增加，这反倒是我们希望看到的结果，也就是说更多的并发用户会需要使用更多的CPU资源。

5.  当需要在尽可能短的时间内，执行完大量GUI自动化测试用例时，业界主流的解决方案是什么？

**考点分析：测试执行架构的设计**

**答案与解析：**

这个问题其实不难回答，业界一般会采用两种方案：

- 一种是，使用第三方的云测服务，比如国外的Sauce Labs、国内的Testin等；
- 另一种是，自己搭建Selenium Grid集群。

其实，这两种方案的本质都是将大量的测试用例以并发的方式来执行。更多的技术细节，你可以参考第39篇文章[《从小作坊到工厂：什么是Selenium Grid？如何搭建Selenium Grid？》](https://time.geekbang.org/column/article/40468)中的相关内容。
