Page 60 - 《软件学报》2025年第7期
P. 60

陈元亮 等: 分布式系统动态测试技术研究综述                                                          2981


                 点. 当前, 用户请求负载合成主要有         3  种方法: 模型驱动的负载生成        (model-driven workload generation)、API 合成
                 和系统测试用例转换技术.

                 3.1.2.1    模型驱动的负载生成
                    通过系统模型自动生成测试负载. 该方法通过理解系统的行为模式和性能特征, 构建模型来模拟实际用户或
                 系统活动. 首先, 测试人员需对分布式系统的架构、功能和用户行为进行深入分析, 构建反映关键行为和性能特征
                 的模型. 随后, 基于该模型, 测试工具可自动生成大量负载测试输入, 用于评估系统性能和稳定性.
                    Bodnarchuk  等人  [88] 于  1991  年首次提出了用于分布式文件系统测试的负载生成模型           SUE. SUE  收集分布式系
                 统在真实环境中的用户数据, 进行特征工程, 构建负载特征描述模型, 识别对系统性能影响最大的工作负载. 基于
                 这些特征, SUE   合成驱动程序生成负载, 持续对系统进行测试. 使用实际数据集作为负载生成基础是一种简单有
                 效的方法, 能够更真实地反映实际使用情况, 但需要对用户隐私数据进行清洗处理. 通过研究分布式工作负载, 研
                 究者发现其具有两个关键特征: 突发性和自相似性. 突发性指的是在短时间内数据包或用户请求剧烈波动; 自相似
                 性则指长时间内呈现相似的周期性波动. 针对这两个特征, 典型负载生成工具 BURSE                        [89] 基于两态马尔可夫调制泊
                 松过程   (MMPP2s) 叠加模型来模拟这些特征. 该模型简单易用, 所需的输入参数可直接从系统日志导出或由性能
                 分析人员提供. 基于此模型, BURSE 能生成大量具有突发性和自相似特征的负载, 用于分布式系统部署前的模拟
                 测试, 有助于评估系统的稳定性与性能.

                 3.1.2.2    基于  API 的负载合成技术
                    手动构建测试模型不仅耗时耗力且缺乏灵活性, 特别是面对不同分布式系统时, 为每个系统定制的负载生成
                 模型往往无法通用, 限制了测试方法的普遍适用性. 鉴于分布式系统通常提供详尽的                           API 文档来描述其对外服务
                 和接口, 这为自动化生成负载测试输入提供了可能. 基于                 API 的负载合成通过利用系统提供的服务接口               (API) 来
                 创建大量测试负载. 该方法的核心在于使用              API 调用序列模拟用户操作或系统交互, 以此来测试并评估分布式系
                 统在处理各种用户请求负载时的性能和稳定性. 为了提高测试效率, 一些动态测试工具采用实时监控技术来获取
                 系统运行的关键信息, 并据此实时调整            API 调用序列的生成策略, 从而有效提升探索系统潜在问题的能力, 深入挖
                 掘特定功能和执行路径的相关缺陷.
                    典型工具如     Swagger [90] 提供的自动化代码生成工具可以用来创建           API 的模拟实现    (Mock servers), 也可以从
                 API 描述文档自动生成测试输入, 允许测试人员在不访问实际后端服务的情况下测试                          API. JMeter [91] 则是另一个广
                 泛使用的开源负载测试工具, 它通过待测系统的               API 描述, 模拟多用户并发访问来测试分布式应用和服务, 包括但
                 不限于   HTTP/HTTPS、SOAP/REST  等服务. 使用    JMeter 进行分布式系统测试时, 测试工程师首先会创建一个测
                 试计划, 其中包含了一系列        API 调用请求, 这些请求模拟了用户对系统的操作. 然后, JMeter 可以在单机上模拟数
                 百到数千个并发用户生成负载, 也可以通过配置多台机器的                   JMeter 实例形成一个测试集群, 进一步扩展测试的规
                 模. 在测试执行过程中, JMeter 收集各种性能指标, 如响应时间、吞吐量和错误率, 帮助开发者识别系统瓶颈和性
                 能问题. 针对分布式微架构服务, 工具           Pact  [92]  设计了一个消费者驱动的契约测试模式, 专为测试分布式系统中的
                 服务间的   API 交互. 它通过在服务的消费者         (客户端) 和提供者     (服务器端) 之间建立契约: 首先是由消费者定义对
                 服务提供者的预期行为, 这些预期形成了一份契约. 这份契约包含了每个                       API 预期的请求和对应的响应. 然后, 这
                 份契约会被传递给服务提供者, 服务提供者利用契约进行自己的测试, 保障其实际行为符合契约规定的预期. 这种
                 方式使得每一方都在确的预期下进行开发和测试, 从而减少了服务间集成时的不确定性和错误.

                 3.1.2.3    系统测例转换技术
                    考虑到大多数分布式系统在开发过程中都会编写大量的系统测试用例                         (包括集成测试和单元测试用例), 用于
                 验证和评估其功能是否符合设计要求. 因此, 一些动态测试工具, Ctests                [22] 、DUPTester [70] 等, 会基于系统自带的测
                 试用例进行分析, 自动转换生成测试用例合成器. 以               DUPTester 工具为例, 它通过将原本的单元测试输入转换为客
                 户端  Python  程序, 生成大量用于系统测试的用户请求负载输入. 具体来说, DUPTester 首先为每个单元测试构建一
                 个抽象语法树     (AST), 然后基于这个    AST  合成一个   Python  程序. 在这个过程中, DUPTester 需要处理直接翻译不
                 能工作的情况. 例如, DUPTester 将一些     Java 库函数和类替换为相应的        Python  函数和类, 如将  Java 的  HashMap  对
                 象替换为   Python  字典对象. 此外, DUPTester 将一些特定于软件的测试方法或软件内部函数替换为可以从客户端
   55   56   57   58   59   60   61   62   63   64   65