Day30-15|9.5.3 可靠性测试用例设计:从真实场景推导可验证的故障证据
Day30-15|9.5.3 可靠性测试用例设计:从真实场景推导可验证的故障证据
一、教材定位
可靠性测试用例不是把功能测试用例简单执行更长时间,而是根据系统运行剖面、故障模型和可靠性目标,设计能够暴露持续运行缺陷、异常处理缺陷和恢复一致性缺陷的测试活动。前一节定义了软件运行剖面,解决“系统通常怎样被使用”的问题;本节进一步解决“用什么具体场景和判定方式验证可靠性”的问题。
可靠性测试用例设计的核心,是把抽象的质量要求转化为可执行、可观察、可复现和可判定的测试证据。比如“系统具有高可用性”不能直接作为测试用例,必须拆解为节点失效、流量转移、请求处理、恢复时间、数据一致性和业务成功率等可观测事件。再如“系统具有容错能力”,不能只验证进程没有退出,还要验证故障被发现、影响被隔离、业务结果正确、恢复后状态一致。
二、可靠性测试用例的基本结构
一个完整的可靠性测试用例至少包括以下内容:
| 要素 | 说明 | 典型问题 |
|---|---|---|
| 用例目标 | 要验证的可靠性属性或机制 | 是验证可用性、完整性还是可恢复性 |
| 前置条件 | 初始状态、版本、配置和依赖 | 系统是否处于可描述的基线 |
| 运行剖面 | 用户、事务、概率和负载 | 场景是否接近真实使用 |
| 故障刺激 | 注入或等待的异常 | 故障发生在什么时机和范围 |
| 操作步骤 | 具体执行顺序 | 是否可以自动化和重放 |
| 观测指标 | 技术指标与业务指标 | 是否能证明影响和恢复 |
| 通过准则 | 可量化的预期结果 | 何时算通过、何时算失败 |
| 清理与回滚 | 恢复环境和数据 | 测试是否会污染后续结果 |
| 证据附件 | 日志、指标、追踪和对账 | 结果能否审计和复核 |
用例标题也应体现“条件—动作—结果”,例如“主库不可用期间执行订单创建,验证流量切换后订单不重复且最终状态一致”,比“测试数据库故障”更清晰。
三、从可靠性目标推导测试用例
1. 从质量属性场景出发
可靠性目标应包含刺激、环境、响应和响应度量。以故障转移为例:在正常生产负载和主节点突然不可用的条件下,系统应自动将请求转移到备用节点,恢复时间不超过目标,已提交事务不丢失,未完成事务按约定重试或补偿。
从这个场景可以推导多个测试用例:主节点进程退出、主机断电、网络隔离、存储不可写、心跳延迟和主备数据延迟。不同故障的检测方式和恢复路径可能不同,不能只设计一个“停止服务”的粗粒度用例。
2. 从故障模型出发
故障模型描述可能发生的故障类型、触发条件、影响范围和可观察表现。常见模型包括进程故障、节点故障、网络故障、依赖故障、数据故障、资源故障、配置故障和人为操作故障。测试用例应覆盖高概率、高影响和高难以恢复的故障。
故障模型不能只关注基础设施。业务层也可能出现状态机错误、重复消息、乱序消息、部分成功、超时后实际已成功和人工重复提交等故障。这些故障经常导致数据不一致,是高级案例题中的重点。
3. 从故障影响出发
同一个故障在不同业务中的影响不同。缓存失效可能只造成性能下降,也可能在缓存承担唯一数据来源时造成业务不可用;消息重复可能被幂等机制吸收,也可能造成重复扣款。用例设计应说明影响对象、影响范围和可接受边界,避免用统一判据评价所有故障。
四、测试用例的主要类型
1. 正常运行用例
正常运行用例按照运行剖面生成真实业务流量,作为可靠性测试的基线。它应覆盖高频交易、核心链路、典型数据和长期运行过程。没有正常基线,就无法判断故障注入后性能和业务结果变化了多少。
正常用例还应考虑数据增长、缓存冷热变化、定时任务、日志累积和连接池复用。短时间内成功并不代表连续运行可靠,因此应设计持续运行和周期性重复执行。
2. 边界和异常输入用例
通过空值、超长字符串、极大金额、极小时间间隔、重复标识、非法状态和不完整消息,验证输入校验、错误处理和状态保护。边界输入可能激活异常路径,也可能导致资源消耗和日志膨胀,因此要观察系统是否稳定返回、是否泄漏敏感信息以及是否留下错误状态。
3. 故障注入用例
主动注入节点宕机、网络延迟、丢包、依赖拒绝、磁盘满、时钟偏移、消息重复和证书失效等故障。每个用例应明确注入开始和结束条件、注入范围、停止保护和预期处置。故障注入不能只验证“系统是否活着”,还要验证故障传播是否被限制。
4. 恢复和回归用例
恢复用例验证故障解除后系统能否回到正常状态,是否需要人工干预,是否存在积压、脏数据或错误配置。恢复完成的判据应包括技术状态、业务状态和数据状态。例如服务恢复不代表订单恢复,必须进一步验证未完成订单是否重新处理、重复消息是否被抑制、对账结果是否一致。
5. 老化和耐久用例
在代表性负载下长时间运行,观察内存、线程、句柄、连接、磁盘、队列、缓存和索引等资源趋势。老化用例必须记录采样周期和趋势阈值,不能只在测试结束时看一次资源值。很多泄漏表现为缓慢增长,只有曲线才能证明是否存在持续积累。
6. 组合故障用例
真实事故可能同时包含网络抖动、节点重启和消息积压。组合故障用例可以验证系统在多个压力叠加时是否出现级联失效。但组合不能无限增加,否则无法定位根因。通常先测试单一故障,再将具有代表性的故障组合,并设置明确的实验矩阵。
五、输入、负载和故障的设计方法
1. 输入数据分层
输入数据可以分为代表性数据、边界数据、历史数据、随机数据和故障数据。代表性数据用于模拟常态,边界数据用于激活极端路径,历史数据用于复现已知问题,随机数据用于探索未知组合,故障数据用于验证校验和恢复。不同数据集要有标识,测试结果才可解释。
2. 负载变化设计
负载可以采用稳定负载、阶梯负载、突发负载、周期负载和恢复负载。稳定负载适合观察长期资源趋势,阶梯负载适合发现容量拐点,突发负载适合验证弹性和限流,周期负载适合模拟批任务,恢复负载适合验证故障解除后的积压处理。
负载不是越高越好。超过系统设计边界后出现拒绝,不能直接说明可靠性不达标。应将目标负载、峰值负载和极限负载分开,并为每种负载设置不同的通过标准。
3. 故障时机设计
同一故障发生在不同阶段,结果可能不同。例如数据库在事务提交前不可用、提交后网络断开、回调发送后进程退出,都会产生不同的一致性风险。因此故障注入应覆盖请求开始、业务处理中、外部调用后、事务提交前后、消息发送前后和恢复期间等关键时机。
六、通过准则与结果判定
可靠性测试必须提前定义通过准则,不能测试结束后根据结果临时调整。常见准则包括:规定时长内无严重故障;请求成功率达到目标;故障检测时间不超过目标;服务恢复时间满足恢复时间目标;数据丢失量为零或不超过允许范围;重复处理数量为零;资源使用不持续增长;告警能够及时产生并正确关闭。
通过准则应区分严重等级。核心交易失败、数据错误和安全越权通常属于严重故障;单个非关键查询超时可能属于一般故障。统计时要记录故障总数、按等级分类的故障数、故障暴露时间、恢复时间和业务影响,不能只用一个平均值掩盖长尾问题。
对于概率性指标,还要说明样本量和置信要求。测试了 10 次没有失败,不能证明低概率故障不存在;如果要估计某类故障率,应增加运行次数和时间,并说明统计方法。案例答题中,即使不写复杂公式,也要体现样本量、观察窗口和统计口径意识。
七、可复现性与自动化
可靠性故障往往偶发,测试用例必须尽量保留可复现条件。应记录代码和配置版本、环境拓扑、数据集版本、随机数种子、故障注入时间、请求标识、节点时钟、依赖响应和日志关联号。这样才能把“偶发错误”转化为可以重放、定位和回归的工程问题。
自动化执行应具有幂等的准备和清理步骤。测试失败后不能假设环境仍然正常,要检查服务状态、消息积压和数据残留。对会产生业务副作用的用例,应使用隔离账户、测试支付渠道或可回滚的数据空间。自动化不是无人监管,必须设置限流、熔断和停止条件,避免测试本身造成系统事故。
八、案例分析:支付回调可靠性用例设计
某支付平台的支付请求由本系统发起,结果通过第三方回调通知。过去测试只覆盖“成功回调”和“失败回调”,上线后出现回调重复、回调延迟、回调顺序颠倒以及本系统已成功但响应丢失等问题。
可靠性测试用例应先建立业务状态和接口语义。测试正常成功、明确失败、回调超时、回调重复、回调乱序、签名错误、回调内容缺字段、系统处理成功但返回第三方失败、系统重启后重新接收回调等场景。每个场景都检查签名校验、幂等键、状态机、重试次数、死信处理、订单最终状态和对账结果。
例如在“本系统完成扣款但响应丢失”用例中,先让支付渠道完成扣款,再模拟网络断开,使本系统收不到同步响应;随后触发查询或异步回调,观察订单是否能从待支付转为已支付,重复通知是否不会重复记账。通过准则不仅是接口返回成功,还包括订单金额、支付流水、库存和对账数据一致,且恢复时间满足目标。
九、综合知识练习
题1
为什么可靠性测试用例不能只写“注入节点故障,检查系统恢复”?
参考答案:该描述没有说明故障时机、运行负载、影响范围、恢复路径、观测指标和通过准则。完整用例应明确节点如何失效、哪些请求正在处理、是否发生流量切换、恢复时间是多少、数据是否一致以及何时判定通过。
题2
设计故障注入用例时,为什么要覆盖事务提交前后?
参考答案:提交前后故障对数据状态和重试语义的影响不同。提交前失败可能安全回滚,提交后但响应丢失可能导致客户端重复提交。如果不覆盖关键时机,容易遗漏重复扣款、重复订单和状态不一致等可靠性问题。
题3
可靠性测试的通过准则应包含哪些维度?
参考答案:至少包括服务可用性、业务成功率、错误率、故障检测时间、恢复时间、数据完整性与一致性、资源趋势、告警效果和残留积压。还应区分故障严重等级,并明确统计时间窗口和样本量。
十、论文写作素材
论文中可以这样描述测试用例设计:
“我依据运行剖面和故障模型设计可靠性测试用例,将正常运行、边界输入、节点故障、网络延迟、依赖不可用、消息重复和恢复回归纳入统一测试体系。每个用例均定义前置条件、故障时机、执行步骤、技术指标、业务指标和通过准则,并记录版本、配置、数据集、随机种子和请求关联号,以保证故障可复现。对于支付、订单等有副作用的操作,重点验证幂等、状态转换、补偿和对账,而不是只观察接口响应码。”
案例题中要避免只罗列“压力测试、容错测试、稳定性测试”。应进一步写出具体刺激、预期响应和度量结果,体现从架构机制到测试证据的对应关系。
十一、今日复盘
- 可靠性测试用例要由目标、运行剖面和故障模型共同推导。
- 用例必须可执行、可观察、可判定、可复现和可清理。
- 正常、边界、故障、恢复、老化和组合故障应按风险选择覆盖。
- 故障注入时机要覆盖事务提交前后和外部调用关键节点。
- 通过准则必须同时考虑技术指标、业务结果、恢复时间和数据一致性。
- 高级案例题的关键不是写测试名称,而是写清“刺激—响应—度量—结论”。