测试工具非功能测试场景自动配比工具相关算法介绍
Posted 非功能之路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测试工具非功能测试场景自动配比工具相关算法介绍相关的知识,希望对你有一定的参考价值。
1 引言
在银行应用系统建设中,非功能测试为数百个系统的高效性能保驾护航,在非功能测试过程中,通常需要根据各交易在生产上发生的频率和比例来设计测试模型,其中交易配比的调试占用较长的时间。目前完成LoadRunner场景交易配比的主要方法是通过手工反复调整Vu和Pacing来实现的,此过程十分耗时。在容量测试中,需要配置多个梯度的场景,工作量大,且工作量会随着交易数量的上升而上升。在交易优化之后,进行复测时,该比例还需要重新调整,费时费力。这时测试场景自动配比工具出现了,其目标就是“一键”完成交易配比。
本文从LoadRunner Automation API的研究使用入手,介绍测试场景自动配比工具的相关算法,讨论其中一种基于最小二乘法的参数预测方法,使程序能够根据多次试运行的结果来自动配置场景的有关参数,通过多次迭代来使交易比例逐步逼近测试模型。而整个逼近过程都不需要人工干预,使之成为一种节约人力成本的有效手段。
2 背景知识
2.1 LoadRunner软件概述
LoadRunner是一种适用于各种体系架构的,预测系统行为和性能的工业标准级负载测试工具。通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner能够对整个企业架构进行测试。通过模拟实际用户的操作行为并实行实时性能监测,帮助用户更快的查找和发现问题。
我行非功能测试使用LoadRunner作为测试工具,通过脚本模拟真实用户的行为,执行LoadRunner场景对被测系统发起并发压力。通过分析TPS、平均响应时间等指标,以及结合系统CPU、内存等资源利用率,评价被测系统的性能,并对测试中出现的错误报告进行分析,定位和解决问题。
2.2 LoadRunnerAutomation API概述
LoadRunner通过在Virtual User Generator中编写LoadRunner脚本来模拟对系统的业务操作;通过在Controller中配置和执行LoadRunner场景来对被测系统发起压力;通过Analysis分析由LoadRunner自动收集的测试结果和数据。
LoadRunnerAutomation API允许不通过LoadRunnerController图形用户界面就能够执行测试场景(Scenario)。通过LoadRunner Automation API可以在应用程序代码中定义和执行场景。
本文讨论的是一种自动配置和执行LoadRunner场景的工具,而这种自动配置和执行功能正是LoadRunnerAutomation API所能够提供的。因此,工具的自动配置、执行和结果收集功能均通过LoadRunnerAutomation API来实现。整个API的核心对象是LrEngine。在创建LrEngine之后,应用程序可以连接到LoadRunner Controller的一个实例,或者创建一个LoadRunnerController实例。
在程序设计中,可通过LrEngine对象来访问Scenario对象,在Scenario对象中配置场景的各种参数,控制场景执行,收集执行信息。
2.3 场景配置与场景控制
1、LrScenario配置
首先新建LrEngine并获取LrScenario的对象:
LrEngine_engine = new LrEngine();
判断Controller是否被打开:
_engine.Scenario.IsOpened()
判断Controller是否正在运行:
_engine.Scenario.DidScenarioRun()
上述条件检查完毕后,新建场景:
_engine.Scenario.New(true,LrScenarioType.lrVusers);
然后清理场景并设置场景的输出目录、是否覆盖等。由于本工具进行场景配置仅仅是为了试验参数配置的效果,故使用一个临时的输出目录,并覆盖结果。
_engine.Scenario.RemoveAllOutputMessages();
_engine.Scenario.ResultDir= "temp";
_engine.Scenario.SetAttrib(LrScAttribs.lrScAutoOverwriteResult,1);
2、LrGroup配置
首先添加脚本,通过传入一个脚本名及其对应的脚本路径:
_engine.Scenario.Scripts.Add(scriptPath,ref scriptName);
然后添加压力发生器。本工具中的压力发生器是可配置的,如使用本机,loadGen的值为“localhost”。调用Connect函数连接压力发生器。
_engine.Scenario.Hosts.Add(loadGen,LrHostPlatform.lrWINDOWS);
LrHostloadGenHost = _engine.Scenario.Hosts.Item[loadGen];
loadGenHost.Connect();
最后通过组名、脚本名、压力发生器、Vu数量4个参数来添加LrGroup到LrScenario中,从而完成LoadRunner场景的组配置,即初步完成各交易的配置。
_engine.Scenario.Groups.Add(groupName);
LrGrouplrGroup = _engine.Scenario.Groups.Item[groupName];
lrGroup.AddVusers(scriptName,loadGen, numOfVusers);
在这里我们就可以通过设置Vu数量来对交易配比进行控制了。
3、Run-timeSettings配置
工具需要通过LoadRunner Automation API来关闭Log、取消Think Time和设置Pacing。由于LoadRunner场景中每个LrGroup的运行时配置是存储在一个键值对形式的字符串中,因此需要首先获取当前配置,包括Run-time Settings(rts)和Action Logic(actionLogic)。通过下面语句:
stringrts = "", actionLogic = "";
lrGroup.GetRunTimeSettings(refrts, ref actionLogic);
获取得到的rts和actionLogic内容。
需要配置的内容包括Run-timeSettings中的LogOptions(设置为LogDisabled)和Options(设置为NOTHINK),还包括Action Logic中的RunLogicPaceType(设置为ConstAfter)和RunLogicPaceConstAfterTime(设置为我们需要的Pacing)。这样就可以通过设置Pacing来调整交易配比了。
字符串修改完成后,通过下面语句使配置生效:
lrGroup.SetRunTimeSettings(rts,actionLogic);
4、Scenarioschedule配置
为了能够同时启动所有Vu,又为了能够设置场景的执行时间,需要通过LoadRunner Automation API来对LoadRunner场景进行ScenarioSchedule配置。
要达到第一个目的,我们需要将默认的Real-world Schedule改为Basic Schedule。
通过调用_engine.Scenario.ManualScheduler.get_Schedule("schedule")来获取一个LrManualScheduleData对象,再通过调用LrManualScheduleData对象的GetScheduleData(outscheduleXML, out errStr)方法获取具有XML内容的string,修改此XML即可完成Scenario Schedule配置。
通过XML中的路径LoadTest->Schedulers->Scheduler->Manual->Global->Scheduling来找到我们要修改的XML内容,改为如下表所示的内容,即可将Run Mode设置为Basic Schedule。
<Scheduling> <IsDefaultScheduler>true</IsDefaultScheduler> <IsClassicScheduler>true</IsClassicScheduler> <DynamicScheduling> <RunAll> <StartCondition> <PrevAction /> </StartCondition> </RunAll> <Duration> <StartCondition> <PrevAction /> </StartCondition> <RunFor>300</RunFor> </Duration> <StopAll> <StartCondition> <PrevAction /> </StartCondition> </StopAll> </DynamicScheduling> </Scheduling> |
表1 将Run Mode设置为Basic Schedule所需的XML
将XML中的RunFor节点中的值设置为需要的场景执行时间(秒),即可完成场景执行时间设置。
通过调用LrManualScheduleData对象的scheduleData.SetScheduleData(scheduleXML,out errStr)方法,并通过调用_engine.Scenario.ManualScheduler.SetCurrentSchedule("schedule")来完成设置。
5、场景的启停
使用下面语句运行场景:
_engine.Scenario.Start();
使用下面语句停止 / 立即停止场景:
_engine.Scenario.Stop(); / _engine.Scenario.StopNow();
3 场景自动配比优化算法
3.1 逐步逼近的交易配比优化方法
这里所采用的逐步逼近的交易配比优化方法,其想法来源是模拟人工配比的过程,通过一次次试配置、运行场景、修正配置这种过程来使各交易比例接近测试场景的要求。
图1 在LoadRunner中手工配置交易配比
手工配置主要是通过设置Vu数和Pacing值来实现。如图所示,需要针对每支交易进行设置,中间过程需要一定的经验和手工计算。配置完成之后,运行场景。
场景运行完成,对比各个交易的TPS与测试场景的要求是否一致。TPS高了,可以减少Vu数量,或是增加Pacing,具体增加多少,可根据它的平均响应时间算得;TPS低了,可以增加Vu数量,一般可以按照测得TPS与目标TPS之间的比例来确定增加多少个Vu,减少Pacing,一般可以减为0,或者按照个人经验给出恰当的值。
3.2 GenerateNext函数
自动比例优化通过GenerateNext(List<Scenario> existingScenarios,Scenario newScenario)函数实现。两个参数分别是前面已经运行过的场景existingScenarios和一个待配置的场景newScenario。函数最终会使newScenario中每一个交易(Group)的Vu和Pacing属性得到配置。其具体实现如下。
首先通过调用FilterMatchingScenarios(List<Scenario>existingScenarios, Scenario newScenario)过滤掉那些跟当前场景交易(Group)不同的场景,从而保证所参考的场景都是与本场景一致的。
然后调用GenerateHistoryGroups(List<Scenario>scenarios),该函数返回一个List<HistoryGroup>,其功能是从多个迭代场景中获取按交易划分的交易历史数据,用HistoryGroup存储一支交易的历史数据,即不同场景中属于同一支交易的多个Group的集合。
这里使用的HistoryGroup对象与Scenario、Group对象的关系如下图所示:
图2 HistoryGroup对象与Scenario、Group对象的关系
每个场景(Scenario)对象中有多个交易(Group)。每一次迭代,场景都会被复制一遍。GenerateNext方法用来根据该交易以往的一系列不同参数以及不同运行统计数据来计算本次的设置,即根据一个HistoryGroup对象计算相应Group的本次设置。
那么目前的问题就变成了如何根据一个HistoryGroup对象来计算一个Group对象的Vu和Pacing属性值。下面将分别针对Vu和Pacing的计算方法进行讨论。
3.3 对于Vu数的预测
对于Vu数的预测策略为根据上一次的结果进行本次的设置。其策略可描述为如下几点:
1. 首次Vu设置为1。
2. 将上一次的运行结果(Vun,TPSn)作为二维平面上的一点,由(0,0)点至(Vun,TPSn)点作直线y=ax,令y=TargetTPS,则将x向上取整的值作本次准备采用的Vu。
图3 对于Vu数的预测方法
3. 若x>Vun,则将x作为新的Vu值,且要令Pacing=0。因为Pacing是作为微调的参数而存在的,且只能让TPS变低,因此此处保留Pacing值就变得没有意义,需要在接下来的迭代中再去估计。
4. 若x=Vun,则继续下一步的Pacing预测。
5. 若x<Vun,且Pacing=0,则将x作为新的Vu值。
6. 若x<Vun,且Pacing≠0,则将Vun作为新的Vu值,即不改变原有值,同时设置Pacing=0。
完成对Vu数的预测时候,在第4种情况下,进行下一步的Pacing预测。
3.4对于Pacing的预测
对于Pacing的预测策略为根据之前所有Vu数与本次配置相同的测试结果来预测本次的Pacing设置。其策略可描述为如下几点:
1. 首次设置Pacing为0。
2. 第二次设置Pacing为1(单位为秒)。
3. 将之前所有Pacing与本次配置相同的运行结果(Pacingi,TPSi)作为二维平面上的点保存在数组中,作为输入参数,通过最小二乘法求得一条反映这些点分布趋势的曲线y=f(x),令y=TargetTPS,则x值为本次将会采用的Pacing值。
图4 基于最小二乘法的Pacing预测
(1) 使用线性最小二乘法预测Pacing
最小二乘法(又称最下平方法)是一种数学优化技术,它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和最小。最小二乘法还可以用于曲线拟合。其他一些优化问题也可以通过最小化能量或最大化熵,用最小二乘法来表达。
我们以(x1,y1),(x2,y2)…(xn,yn)作为输入,采用m+1个参数m次最小二乘法,n>>m,对于拟合曲线y=a0+a1*x+a2*x2+…am*xm,可得到一组参数a0、a1…am,因此拟合曲线便可以确定。y=a0+a1*x+a2*x2+…am*xm即是所求函数。
(2) 使用线性最小二乘法预测Pacing
为了实现简便和不依赖其他第三方库,这里采用了线性的最小二乘法来作为Pacing的预测方式。我们以(Pacing1,TPS1)(Pacing2,TPS2)…(Pacingi,TPSi)作为输入,以TPS=a0+a1*Pacing作为拟合曲线,通过最小二乘法求得a0、a1的值,从而得到拟合直线TPS=a0+a1*Pacing。令y=TargetTPS,则x值为本次将会采用的Pacing值。
4 结束语
目前软件可以按照设计要求,实现测试场景配置、LoadRunner运行控制、运行结果收集和数据展示、运行结果分析和场景参数自动优化功能。能够正常地与LoadRunner 11.0配合使用。拥有基本的容错能力,拥有较流畅的使用体验。
以上是关于测试工具非功能测试场景自动配比工具相关算法介绍的主要内容,如果未能解决你的问题,请参考以下文章