购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4 适应度函数测试金字塔

适应度函数测试金字塔的概念与功能测试金字塔的概念密切相关。我已经调整了适应度函数和架构指标的主要概念,以便在架构测试中重用以达到平衡(这个想法在架构验证中同样重要)。

统计学家George Box曾写道:“所有模型都是错误的。”但他又补充说:“但仍有一些模型是有用的”。 [4] 我希望这里介绍的模型属于有用的一类。

就像功能性金字塔一样,最简单最便宜的测试位于金字塔的底部,较高级的测试位于中间,而最复杂、应该提供“最佳”真实反馈的测试则位于适应度函数测试金字塔的顶部。

适应度函数总是跨越多个类别创建的,我在2.2节介绍了这些类别。虽然所有的强制型适应度函数类别都与描述一个有用的适应度函数相关,但只有少数类别与适应度函数测试金字塔层中的分类相关。因此,我鼓励大家使用适应度函数测试金字塔的概念来创建一套平衡的架构测试,在运行时间和运行维护成本与这些(大多是自动化的)架构测试所提供的信心之间取得平衡。

我将只在某些环境中考虑执行(快与慢)作为适应度函数测试金字塔中层分类的相关因素。如图2-3所示,将适应度函数及其测试实现分类到金字塔某一层的两个最相关的类别是反馈广度(原子性与整体性)和执行方式。

图2-3:影响适应度函数测试金字塔层的类别

只有整体适应度函数才会出现在金字塔的顶层。至于执行,连续运行的测试和验证更难实现,尤其是整体反馈。因此,这些类别相互作用,决定了每一层的内容。

2.4.1 顶层

顶层测试具有整体性,能为终端用户提供有关系统健康状况及其功能的最复杂的反馈。因此,这些指标和验证最接近真实用例。

然而,它们通常是最难构建和维护且成本最高的测试。在某些情况下,它们也更有可能出现非确定性行为,因为它们涉及许多组件,测试的是系统的大部分。我们在积极寻求对整个系统的整体反馈,但也必须考虑到难以隔离的意外错误。

总而言之,顶层测试的构建和维护都很复杂,它们发现的问题有时很难追根溯源。因此,我们只选择几个“好”的测试,因为我们试图在工作量和产出之间取得平衡(金字塔顶端的测试更少)。

看一个顶层整体测试的例子:对于一家网上商城,我们可以持续度量每分钟结账率、每分钟收入或每分钟登录次数等关键指标,看它们是否在目标区域的预期范围内。如果出现偏差,就会凸显出需要解决的潜在技术问题(也可能是最新部署带来的问题)。顶层还包括混沌工程 [5] ,即在生产环境中引入错误来测试系统的韧性,同时度量系统的总体性能和是否已经为终端用户做好准备。

2.4.2 中间层

如图2-3所示,中间层由触发式整体适应度函数或连续式原子适应度函数组成。这些适应度函数对整个系统的健康状况提供广泛的反馈,但不会持续运行;它们由专门的开发行动触发。

触发的整体指标可能是作为集成测试构建的一部分,或通过利用自动部署流水线中的测试系统或阶段进行测试、执行和评估的指标。使用多个测试用例的集成测试运行还可以通过模拟其他系统部分或第三方系统的故障,对整个系统的性能、事务行为或韧性提供可靠的反馈。适应度函数示例2-3和示例2-4可视为中间层的测试。

在生产系统中持续评估的简单原子适应度函数也属于这一层,例如,对事务持续时间或终端用户性能(如网络应用程序的浏览器加载时间)等原子值进行实时监控和度量。

2.4.3 底层

适应度函数测试金字塔的底层包含“触发式原子”适应度函数。它们通常易于实施和运行,而且成本低廉。由于其简单性,它们通常已经很好地建立并集成到持续集成/持续交付(CI/CD)流水线中。这些构成了定义有用指标的基础。这一层可能包括代码覆盖率指标、静态代码分析(如圈复杂度)或简单的性能测试。

建议为底层打下坚实的基础,然后在上层使用平衡的方法。可以在不创建任何顶层测试(甚至中间层测试)的情况下使用适应度函数。类似地,在某些情况下,你甚至可能需要将金字塔倒置,使用大量连续式整体测试来度量,而在触发式原子类别中只有少量测试。这在很大程度上取决于具体情况和目标,但通常我建议遵循金字塔的形状,在底层进行最多的测试,在上层进行较少的测试。

然而,当我们考虑底层应该有多少个测试时,这个类比就不成立了。通常,如果单元测试能提供这种粒度的价值,就不会有人去考虑限制单元测试的数量。相比之下,对于适应度函数测试金字塔底层,我不建议创建尽可能多的测试,因为它们都会产生额外的开销。 1jIGYpEhi0iOXR20f9Ek1AOyKJCm6VK/EPEP39aH6bUf1qYm6uILpb8whhfK/0Zp

点击中间区域
呼出菜单
上一章
目录
下一章
×