2.3.2 可测试性特征
可测试性主要通过可控制性、可观测性、可追踪性及可理解性等要素来表征,当然,在特定的场景中,预见性、简单性、稳定性也是表征软件可测试性的重要特征。软件可测试性特征及其维度如图2-11所示。
例如,某软件系统由两个不具备可观测性和可控制性的单元A和B构成,这两个软件单元及软件系统不具备可测试性。那么,如何改善这两个软件单元及软件系统的可测试性呢?显然,只要在单元A和B之间增加一个接口,使单元A的输出(状态信息)能够在该接口被观测到,同时通过接口能够向单元B输入数据,就能够对单元B进行控制。通过如此处理之后,由单元A传递给单元B的数据就可以被观测和控制,且具有可预见性,从而使得该软件系统具有满足需求的可测试性。图2-12展示了该软件系统可测试性的改进方法。
图2-11 软件可测试性特征及其维度
图2-12 软件系统可测试性改进方法示例
2.3.2.1 可控制性
可控制性是指在确定的条件下,在配置空间操作或改变系统的能力,包括状态控制、输入输出控制。可控制性一般包括如下四个层面。
(1)业务层面:业务流程以及业务场景易于分解,可实现分段控制与验证。对于复杂业务流程,则需要合理地设定分解点,确保测试过程中能够对其进行有效分解或切片。
(2)架构层面:采用模块化设计,各模块支持独立部署和测试,具有良好的独立性和可隔离性,便于构造Mock环境,模拟依赖关系。
(3)数据层面:测试数据具有良好的可控制性,以便构建多样性测试数据,满足不同的测试场景需求。
(4)实现层面:可控制性的技术实现手段涉及多个方面。例如,在系统外部直接或间接控制系统状态及变量,方便的接口调用,运行时的可注入能力,私有函数及内部变量的外部访问能力,轻量级的插桩能力,面向切面编程(Aspect Oriented Programming,AOP)等技术,实现预期的可控制性。
2.3.2.2 可观测性
可观测性是指在确定的条件下和时间内,基于输出描述系统状态的能力,即通过外部获取系统内部状态信息,评估其状态能力的难易程度。对于一组操作或输入,系统产生预期、明确及可视的响应或输出。所谓“可视”是指运行时及过程可视,在时间维度上,还包括当前和过去的可视,而且是可查询的。输出是可视的基础。工程上,通常采用输入、输出的个数之比(Domain/Range Ratio,DRR)度量信息的丢失程度,DRR值越大,说明信息丢失越多,错误隐藏越多,可测试性越差。在输入个数不变的情况下,输出参数越多,就能够获取更多的信息,发现更多的错误,系统的可测试性就越好。
通过分级事件日志、调用链路追踪信息及各种聚合度量指标,识别输出,基于可测试性接口获取系统内部自检上报信息,确保影响软件行为的因素可视,提高可观测性。在云原生环境下,OpenTelemetry将事件日志、追踪信息及度量指标统一起来,实现数据互通及互操作,较好地解决了信息孤岛问题。
工程上,通常使用日志、度量、追踪等输出,评价系统的可观测性。日志是有时间戳、不可改变的离散事件记录,用于识别系统中不可预测的行为,洞察软件系统发生错误时的行为及变化,一般以结构化方式读取日志,如JSON格式,便于日志查询和自动索引。度量是监控的基础,会在一段时间内汇总并提供度量结果。在分布式系统中,当一个单独的事务或请求从一个节点移动至另一个节点时,追踪允许深入了解特定请求的细节,以确定哪些组件会导致系统错误,如监测通过模块的流量,找到性能瓶颈。
监控是可观测性的一部分,可观测性是监控的超集。两者的主要区别在于主动发现问题的能力。主动发现问题是可观测性的关键。可观测性从“被动监控”向“主动发现与分析”方向发展。可观测能力可划分为告警、应用概览、排错、剖析和依赖分析5个层级。告警与应用概览属于传统监控范畴。对于触发告警,往往具有明显的症状及表象,随着系统架构愈发复杂以及应用向云原生部署方式转变,没产生告警并不能说明系统不存在问题。因此,对于系统内部信息的获取与分析尤为重要。这部分能力主要体现在排错、剖析和依赖分析,这三者体现了“主动发现与分析”能力,逐层递进。
无论是否触发告警,基于主动发现能力,能够对系统运行状态进行诊断,通过指标呈现系统运行的实时状态。一旦发现异常,逐层下钻定位问题,必要时进行性能分析,有利于基于数据分析,增进对系统的认识,预测和防范故障发生。调取模块与模块之间的交互状态,通过链路追踪构建整个系统的“上帝视角”。图2-13给出了系统可观测性与监控的关系。
图2-13 系统可观测性与监控的关系
可观测性对系统的可控制性具有重要影响,系统状态信息对于系统的可测试性具有决定性的作用。但如果无法获得准确的状态信息,就无法判断在下一步是否需要进行控制变更。如果不能对状态及变更进行有效控制,可控制性就无从谈起。可观测性与可控制性相辅相成,缺一不可。DevSecOps的基础就是监控和可观测性。可观测性是一个聚合系统产生的所有数据的解决方案,而监控则是一种收集和分析从单个系统中提取的预定数据的解决方案。监控只显示数据,可观测性则可以借助基础设施度量多个应用程序、微服务、服务器以及数据库的所有输入和输出,支撑系统的健康监测。
2.3.2.3 可追踪性
可追踪性是指跟踪系统行为、事件、操作、状态、性能、错误以及调用链路的能力,主要包括如下几个方面:
(1)记录并持续更新全局逻辑架构视图与物理部署视图。
(2)跟踪记录服务端模块间的全量调用链路、调用频次及性能数据。
(3)跟踪记录关键流程的函数执行过程、输入输出参数、持续时间及扇入扇出信息。
(4)跟踪记录跑批类作业的执行溯源。
(5)打通前端和后端调用链路,确保后端流量的可溯源性。
(6)实现数据库和缓存类组件的数据流量可溯源。
(7)以确定的周期为频次进行异常分析。
2.3.2.4 可理解性
可理解性是指获取软件系统信息并予以理解的能力,包括信息获取的难易程度以及信息本身的完备性、易理解性。其包含但不限于如下内容:
(1)任务定义完整、准确,关注点分离。
(2)系统行为可以进行确定性推导及预测。
(3)设计模式遵循行业通用规范,能够被很好地理解。
(4)文档、流程、代码、数据等信息齐套、完整、准确,易于理解。