一篇文章带你上手性能测试框架K6

2023-07-04  质量实验室 

作者:赵泽鑫 |QE_LAB

K6的简单介绍

K6是一个现代化的、开源的负载测试框架,可以帮助开发者和测试人员对Web应用程序、API以及微服务进行性能测试。K6基于JavaScript编写,简单易学,不需要额外的编程语言或工具。同时该框架社区生态也很好,有很多拓展可以根据需要灵活的进行选择。

使用K6,用户可以创建自定义的性能测试脚本,模拟多种负载场景,包括并发用户数、请求速率、请求类型、网络带宽等,在真实的环境中对应用程序进行压力测试,发现问题并进行优化。

K6还提供了丰富的测试报告和分析工具,可视化展示测试结果,帮助用户快速定位性能瓶颈和优化方案。K6支持多种协议,包括HTTP/2、WebSockets、gRPC以及SSL\TSL。

安装K6的方式很简单,Mac电脑直接使用brew install k6进行安装即可。同时它也支持dockerdocker pull grafana/k6 。运行测试使用K6 run file_name。同时支持添加参数,比如虚拟用户(virtual users)和持续时间(duration)等。

K6 执行模式

Local: 测试完全发生在一台机器、容器或者CI服务上 k6 run script.js

Distribute:测试通过K8S集群分布式的执行kubectl apply -f /path/k6-resource.yaml

Cloud:测试执行在K6的cloud上k6 cloud script.js

简单的K6测试的生命周期

  1. init code, 一般指的是需要加载的本地文件、K6 options的定义和import一些必要的module。
  2. set up code,测试需要的前置步骤,一般是测试需要的数据以及测试环境的初始化。
  3. VU code,测试代码一般在这里,处理一些测试必要的逻辑,一般是API调用逻辑以及度量的指标。对于K6而言,虚拟用户本质是javascript实现的平行的while (true)循环。K6还提供了额外的生命周期函数给我们使用,以应对复杂的业务逻辑,在VU code中还可以使用scenario function来代替default function。关于scenario后面会详细讲解。
  4. tear down code,一般包括测试结果的处理以及关闭测试环境和数据回收。

K6框架中的重要组成部分

1. HTTP request

支持丰富的HTTP请求类型,包括batch\put\post\get\delete\等。

HTTP Request Tags

tag是K6为了更好的筛选测试结果,默认是会自动给每个HTTP请求打tag的,tag的类型包括期望的响应内容、URL、分组名称和场景。

URL Grouping

通常情况下,一个 URL会被默认分配一个URL tag,如果是动态的URL路径,我们就不希望有这种行为,因为会给tag带来大量的独特URL,导致难以管理并且这些独特的URL值是没有什么意义的。所以更好的方式是使用grouping功能,在组内给一个共同的名字。比如请求id要1-100作为一次查询,这时候需要将id作为参数传递进去然后循环100次,每次用不同的id,每次打上一个相同值的name tag。这100次请求组成的group就能使用name共同管理。metrics也支持group,会对一个group进行度量。

2.Metrics

metric是衡量在测试条件下的系统性能,默认情况下,会收集所有的内置metrics指标,如下图:

当然K6也支持自定义metrics,可以在VU code执行阶段声明自定义的metrics,可以获取某个支持数据的trend,也可以获取某个支持数据的counter,比如某个请求的错误总数,成功总数、相应时间,等待时间,数据接收时间的趋势,这样K6在执行结束后会按照声明的metrics输出相应的数据。

3. Thresholds

阈值通常是和metrics绑定使用的,K6支持我们给需要监控的指标设置thresholds,它能自动化的检查SUT(system under test)的性能是否满足期望。比如某个threshold可以设定为:每个request相应时间都小于200ms或者小于1%的request会返回error。我们可以根据metrics的数据自定义任何合理的阈值。测试执行中一旦不满足设定的阈值,那么测试就会以失败的状态终止。

Thresholds编写格式

一个基本的Thresholds由metrics-name 和 threshold-expression组成的,前者很好理解,一般使用内置的metrics指标对应的名称,也可以使用聚合方法自定义对象使用。后面的语法是aggregation_method operator value其中聚合方法就是K6提供的四种,分别是counter、trend、gauge、rate。

在threshold中使用check

check也是K6提供的一种断言方式,但是与threshold不同的是,check并不会导致不满足预期停止测试这样的结果,所以如果只想作为断言而不影响整个测试的话,check是一种很好的选择。

4. Options

K6提供了很多方式增加配置选项,default —> config —>script options —> environment variables —>CLI flags,如果多个同时设置的话,对于K6而言,优先级时按照顺序递减的。PS(如果在命令行中直接添加options,优先级是最高的)。通常情况下,script options 的方式是最常用且灵活的,options作为一个object设置在脚本中,程序运行的时候再去读取。

5. Scenarios

scenarios功能是K6框架的一大亮点,使用的时候很灵活方便,我们可以更简单的组织我们的测试以应对不同的业务场景。不同的场景间可以自定义VU数量,duration time等各种指标以满足测试需要。同时不同场景间是可以定义并行还是顺序执行的,不同的场景可以设置只属于该场景的metrics和tags。

scenarios配置的几个要素

executor:必须的值,定义执行者类型,不同的executor有不同的效果,比如Constant VUs就是VU数量不变的情况下在一定的时间内执行尽可能多的iteration,Ramping VUs就是可变的VU数量在一定时间内执行尽可能多的iteration。shared- iterations是iteration在一定数量的VU间共享,不保证VU的分配,会导致执行快的VU执行了更多的iteration。如果想要合理的分配就要使用Per VU iterations,每个VU都有自己要执行的iteration数量。

vus:虚拟用户的数量。

itrations:迭代次数。

startTime:测试开始后的时间偏移,默认是0s。

K6项目中用例的通用结构设计

如果是单个API的性能测试,那直接采用基本的用例结构,将单个接口的调用写在default function中,配置相应的option执行即可。如果是多个API组合成的业务场景,那就使用scenario,单个API的调用逻辑写在相应的文件中,然后由场景进行组合形成用例。测试数据、metrics、reporter和util这些辅助测试的数据也单独成文件进行管理。这样辅助测试文件和场景用例组合在一起就形成了一个合理的项目结构了。demo传送🚪

测试阈值

测试阈值的选择是做性能测试不可避免的一个重要环节,从测试类型来看一般存在三种方式,每种方式的数值选择都不同。第一种是想要验证系统性能能不能满足实际的业务需求,这种一般称为负载测试。第二种是在不断的加压下想要得到系统的性能上限,一般称为压力测试。第三种一般是关注于系统一定压力下的长时间运行,一般称为浸泡测试。负载测试需要我们根据实际业务来判断,可以访问终端用户或者在prod环境数据作为参考来设置不同场景的性能测试环境以及数据量。压力则是多次进行实验,梯度加压直到系统处理上限,最终得到一个数据量。浸泡测试是基于一定的数据量,这个数据量可能是平均值也可以是中位数这样子能代表整体的数据,然后经过长时间的测试,最终得到系统在长时间的压力下所产生的性能和可靠性问题。

测试结果

测试报告

K6本身是没有图形化界面的测试报告的,它的测试结果只是以一种标准的格式输出在控制台中。为了能够适配不同的需求,我们可以使用K6的拓展来完成测试结果的图形化,比如HTML的报告就可以使用https://github.com/benc-uk/k6-reporter,它的原理是使用handleSummary()以一个object的方式接收测试结果然后进行相应的处理。

181°/1818 人阅读/0 条评论 发表评论

登录 后发表评论