【.com快译】众所周知,功能测试通常侧重于单个用户对目标应用程序的基本体验。对于成百上千用户同时访问目标站点的场景,尤其是那些面向公众的Web应用,开发者必须在应用上线前模拟真实的并发访问情况,并通过考量和负载测试,以充分为任何可能出现的问题和事故做好准备。在本指南中,我将通过以下四个阶段向您介绍负载测试过程。规划:为什么要测试?测试什么?编写测试脚本:如何测试?执行:针对应用程序运行测试脚本。分析和报告:发现了什么?需要修复什么?规划负载测试在规划阶段,团队聚集在一起讨论和确定目标、范围、所需资源和测试场景等方面。这个阶段的交付物是测试计划。但形式上是否正式,还要看团队的实际要求。值得注意的是,任何测试计划都是一项团队活动,我们需要所有利益相关者(即:参与测试或可能受测试影响的任何人)的投入。要求我们要搞清楚为什么要做负载测试?这个问题看似简单,但不同的利益相关者可能会给出不同的测试场景需求。因此,为了达成共识,最好将负载测试的目标制定为非功能性需求(nonfunctionalrequirements,NFR),以定义应用程序期望的状态,并且可以包括团队确定的性能阈值。例如:基于响应时间的要求,注册用户登录的时间不应超过3秒(即达到90%的响应时间)。可见,好的需求往往可以满足:SMART(Specific、Measurable、AgreedUpon、Realistic、Timely)等特性。而在实践中,我们可以从以下几个方面进行控制。范围同意负载测试的共同目标。我们既可以缩小测试内容的范围,又可以让每个成员都知道哪些部分不需要测试。先决条件在进行测试之前,我们需要考虑资源和先决条件,包括:参与者的数量、执行测试所需的时间以及测试数据的环境要求。虽然我们并不总是需要单独的测试环境来进行负载测试,但如果需要,应该提前通知DevOps等团队。负载建模负载模型可用于描述模拟负载的一组特性。例如:用户最常访问哪些页面、哪个服务部分、最长访问时间段和地理位置等。您可以将这些因素嵌入到您的测试脚本中,以更真实地模拟可能对您的应用程序造成的流量和影响。服务器监控在测试过程中,我们经常需要使用脚本来监控后台服务器上的各种告警和日志。如果您的负载测试工具检测到明显的性能下降,您需要能够通过关联服务器上的相应信息来调查它。但值得注意的是,任何形式的监控都会增加现有服务资源的开销,因此整个团队应提前确定需要监控和跟踪的指标和信息。测试场景设置测试和模拟的场景,往往可以帮助我们更准确地获取网站和应用程序的真实性能。例如:我们可以创建典型工作日的负载曲线,模拟大促销期间的峰值负载曲线,模拟生产中断时的场景。可以为我们收集不同的测试场景如:时长、并发用户数、请求数、激增周期(即:应用从0用户到最大用户数的速度)、“峰谷”负载(即:整个测试过程中,每秒请求数的波动)等,可供分析参数数据。在设计负载测试计划时,既可以包括多个用户故事线,也可以使用各种Trello卡片(译者注:卡片式任务管理工具)。该工具的输出格式并不重要;重要的是每个成员都能够从中解释一致的、标准化的测试结果。编写测试脚本在前面规划阶段的所有准备工作完成后,我们现在可以开始准备通过编写负载测试脚本来实施测试。工具选择目前市场上有很多负载测试工具。出于对使用中各种工具的考虑,以及财务和供应商的考虑,我们可能无法按需自由选择负载测试工具,但以下几个方面是值得我们认真考虑的:资源和成本的整体采购价格,它的定价模型是否允许用户根据需要扩展使用量?他们真的需要构建自己的解决方案,还是应该购买端到端的负载测试解决方案?团队拥有哪些技术技能和工具经验?谁将负责测试?应用程序使用的协议和技术是否受支持?测试工具和相应脚本语言的学习曲线是否“陡峭”?测试工具能否让多人轻松协作并处理同一个脚本?测试工具是否可以添加到CI/CD流水线中?该工具是否提供了一种设置性能阈值或服务水平目标(SLO)的简便方法?)?测试结果是否可以显示在可用的报告中,是否可以与现有的数据可视化工具集成?支持如果出现问题,是否可以额外付费获得客户支持?在线帮助文??档是否足够?是用于经验分享的用户社区?扩展负载测试单个负载生成器每秒可以模拟多少个虚拟用户或请求?它能处理测试产生的大量数据吗?能否根据用户的位置特点,从不同的地理位置实施测试?是否允许用户从云端生成负载?鉴于以上需求,我选择了k6(https://k6.io/)作为开发负载测试脚本的工具。总的来说,k6有以下三个优点:由于它是开源的,任何人都可以下载该工具并亲自试用它的脚本。由于它是用JavaScript编写的,因此使用过Cypress、Puppeteer或Playwright等工具的前端开发人员或测试人员可以轻松上手。由于它可以在单机上产生数万个并发用户,所以即使在负载增加的情况下也很划算。当然,下面讨论的步骤也适用于其他工具。此外,我强烈建议您使用各种工具进行自己的概念验证,以找到最适合您的特定情况和测试场景的工具。安装设置如果你使用的是Mac系统,你可以使用Brew轻松安装k6,即:从终端运行--brewinstallk6,几秒钟就可以搞定。当然,如果您使用的是其他操作系统,请使用链接--https://k6.io/docs/getting-started/installation/获取详细的安装说明。一个基本的k6测试脚本下面的JavaScript代码片段展示了最基本的k6测试脚本:importhttpfrom'k6/http';exportdefaultfunction(){letresponse=http.get('https://test.k6.io');}脚本将发送一个HTTPGET请求到一个简单的测试站点(它的URL是https://test.k6.io)。请将代码复制到文本编辑器中并将其保存为test.js文件。然后,可以使用命令--k6runtest.js来运行,得到如下显示结果:脚本的1次迭代。而HTTP测试请求的响应时间为128.2毫秒(即:http_req_duration)。让测试脚本更真实显然,上述脚本的GET请求过于简单,无法用负载测试脚本模拟真实用户在数量和地域分布上的访问情况。而如果负载测试脚本不够真实,在测试过程中会产生误报,甚至无法让用户发现应用组件潜在的性能问题。接下来,让我们讨论一下如何使测试脚本更加逼真。添加静态资源如果您的页面包含浏览器自动检索的图像或脚本等静态资源,请确保您的测试脚本也检索此类资源。毕竟它们会影响您获得页面的响应时间。当然,如果你已经获得了第三方提供商的许可,你也可以考虑从第三方获取静态资源。设置缓存和cookie行为虽然第一次访问站点的访问者无法调用本地缓存的资源,但重复访问者会从缓存中检索相应的资源。对此,我们应该检查负载测试工具的默认缓存和cookie管理设置,并根据需要更改它们以匹配真实的测试场景。添加“思考时间”真实用户通常不会一遍又一遍地刷新同一个URL。导航到目标网站后,他们会花一些时间阅读页面上的内容,并与页面上的一些组件进行交互。这些用户的“思考”时间其实就是各个请求之间的延迟。因此,通过添加1到5秒的“思考时间”,我们可以避免应用程序服务器受到机器人请求的轰炸。使用不同的用户旅程用户旅程是用户如何与应用程序交互的流程,包括:他们访问了哪些页面、他们输入了哪些信息等等。我们在规划阶段建立的工作负载模型可以直接反映系统中最常见的用户流程,例如:使用不同的浏览器登录,或者从购物车中选择商品进行支付等。在k6中,我们可以这样做通过添加不同的场景,而其他工具可能称之为线程组或执行组。添加测试数据正如普通用户不会一遍又一遍地搜索相同的关键字,或者同时使用同一个测试帐户在任何地方登录一样,我们的测试脚本也不应该一遍又一遍地使用相同的数据。如果多个虚拟用户使用同一个账号登录,可能会导致他们的响应被缓存,从而缩短响应时间或增加错误率。为此,您需要修改脚本以从某个CSV文件中获取测试数据以添加真正的随机性。设置测试参数测试参数往往可以通过调整测试用户数的涨跌来改变用户负载的时间趋势,进而帮你画出虚拟用户数随时间变化的曲线图。k6体现的负载测试期间虚拟用户数量的变化设定了失败标准。模拟真实用户的一个重要环节就是找出哪些因素会导致用户访问失败。您可以通过添加响应验证、检查和阈值(包括响应时间或错误率的阈值)来将失败标准添加到测试脚本中。同时,您可以根据实际情况灵活调整这些与性能相关的标准。基于以上讨论的几点,我对原来的k6基础脚本进行了修改,使其更接近真实的测试情况。在参考链接-https://gist.github.com/nicolevanderhoeven/fb74cd9769c8abf95eeb8765a49398cb中,还包含一个带有登录凭据的CSV文件。执行负载测试让我们继续使用上面的k6脚本,通过执行以下命令触发负载测试的运行:k6ru??ntest.js该命令将根据文件中现有的测试参数在本地执行k6脚本。这种小型验证性测试通常被称为shakeout测试。当然,我们随后将在基础设施上运行更复杂的负载测试。测试的真实性当您在数据中心的主机上运行负载测试时,由于测试与应用程序服务器在同一网络上,响应时间将比用户实际体验的要快得多。因此,我们应该尽量将负载生成器的位置与用户的物理位置相匹配。为此,在云中运行测试是为您的测试添加真实感的一种简单方法,尤其是当您的大多数最终用户都在您的组织外部时。对于上面的例子,你可以通过链接——https://app.k6.io/account/register注册一个k6云账号(前50次测试免费)。由于k6本身是开源的,你也可以在自己的云基础设施上运行它。当然原生的k6云服务会更直接好用。拥有账号后,可以通过链接——https://app.k6.io/account/api-token复制APItoken,然后在终端运行如下命令授权本地k6运行你的account:k6logincloud–token认证成功后,可以选择在云端运行如下命令:k6cloudtest.js下图是k6执行的负载测试结果。图中的执行方式(execution)表示你在云端运行测试。由于您的测试将默认在美国阿什本地区的k6AWS账户中运行,因此您可以使用云执行选项(参见--https://k6.io/docs/cloud/creating-and-running-a-test/cloud-tests-from-the-cli#cloud-execution-options),将此设置按虚拟用户的比例分配给其他区域。分析负载测试结果和报告尽管我们在逻辑上将分析过程与执行步骤分开,但两者实际上是重叠的。也就是说,上面的k6输出截图其实包含了k6云仪表盘的链接,方便我们在测试运行时实时查看测试结果。这种实时监控的测试方式可以让用户在问题出现时及时发现,并在需要修复时暂停测试。如果测试由多个负载生成器执行,那么k6有一个统一的仪表板来显示测试的整体概况。k6Cloud负载测试后的结果示例如果出现大量错误,或者响应时间明显表明某个组件无法处理负载,我们应该立即停止测试并获取必要的信息以提出性能建议针对出现的瓶颈进行改进和解决。当然,k6也会帮助用户创建一个dashboard的可分享链接(见--https://app.k6.io/runs/public/f6ad87cec7a24a8c82e46c816e67c4b3),以便相关团队找出测试数据背后的真正原因.虽然这些带有测试结果的共享仪表板对于敏捷团队来说已经足够了,但对于某些项目来说,可能需要一份正式的测试记录摘要报告。毕竟负载测试的目的不是测试本身,而是对结果的处理。我们需要将测试结果清楚地传达给利益相关者,以便我们可以更有效地解决各种性能问题。原标题:负载测试的端到端指南,作者:NicolevanderHoeven
