简介

k6 是一个压力测试套件,使用 golang 编写。主要特性有:

  • 提供了友好的 CLI 工具
  • 使用 JavaScript 代码编写测试用例
  • 可以根据性能条件设置阈值,表明成功还是失败

k6 没有使用 nodejs 而是 golang 程序,通过包裹了一个 JavaScript 运行时来运行 JavaScript 脚本,因此不能直接使用 npm 包以及 Nodejs 提供的一些 API。

同时,k6 在运行测试时,没有启动浏览器,主要用于测试页面以及 API 加载速度。k6 提供了通过网络请求(HAR)生成测试脚本的方法,实现更简便的测试脚本编写,以及 session 的维护。

安装

在 Mac 上比较简单,直接使用 HomeBrew 即可安装:

brew install k6

其他平台官网也提供了相应的安装方式,比较特别的是提供了 Docker 的方式运行。

使用

直接使用 k6 的命令运行测试,官网提供了一个例子:

k6 run github.com/loadimpact/k6/samples/http_get.js

也可以编写自己的测试脚本:

import http from "k6/http";
import { sleep } from "k6";

export default function() {
  http.get("https://www.thoughtworks.com");
  sleep(1);
};

保存文件 script.js 后运行 k6 命令

k6 run script.js

然后可以看到 http 请求的各项指标

        /\      |‾‾|  /‾‾/  /‾/   
     /\  /  \     |  |_/  /  / /    
    /  \/    \    |      |  /  ‾‾\  
   /          \   |  |‾\  \ | (_) | 
  / __________ \  |__|  \__\ \___/ .io

  execution: local
     output: -
     script: k6.js

    duration: -,  iterations: 1
         vus: 1, max: 1

    done [==========================================================] 1 / 1

    data_received..............: 108 kB 27 kB/s
    data_sent..................: 1.0 kB 252 B/s
    http_req_blocked...........: avg=2.35s    min=2.35s    med=2.35s    max=2.35s    p(90)=2.35s    p(95)=2.35s   
    http_req_connecting........: avg=79.18ms  min=79.18ms  med=79.18ms  max=79.18ms  p(90)=79.18ms  p(95)=79.18ms 
    http_req_duration..........: avg=639.03ms min=639.03ms med=639.03ms max=639.03ms p(90)=639.03ms p(95)=639.03ms
    http_req_receiving.........: avg=358.12ms min=358.12ms med=358.12ms max=358.12ms p(90)=358.12ms p(95)=358.12ms
    http_req_sending...........: avg=1.79ms   min=1.79ms   med=1.79ms   max=1.79ms   p(90)=1.79ms   p(95)=1.79ms  
    http_req_tls_handshaking...: avg=701.46ms min=701.46ms med=701.46ms max=701.46ms p(90)=701.46ms p(95)=701.46ms
    http_req_waiting...........: avg=279.12ms min=279.12ms med=279.12ms max=279.12ms p(90)=279.12ms p(95)=279.12ms
    http_reqs..................: 1      0.249921/s
    iteration_duration.........: avg=4s       min=4s       med=4s       max=4s       p(90)=4s       p(95)=4s      
    iterations.................: 1      0.249921/s
    vus........................: 1      min=1 max=1
    vus_max....................: 1      min=1 max=1

运行压力测试时,需要增加更多的虚拟用户(VU),vus 参数和持续时间的参数:

k6 run --vus 10 --duration 30s script.js

编写测试脚本的一些规则

default 方法是用于给每个 VU 以及每次迭代重复运行的,因此需要把真正的测试代码放到这个方法中,例如访问某个页面。

为了保证测试的准确性,一些初始化的代码不应该放到 default 方法中。尤其是文件的读取等依赖环境上下文的操作不能放到 default 方法中执行,这样做也会丢失 k6 分布式运行的能力。

前面提到的命令行参数,例如指定虚拟用户数量 --vus 10,这些参数也可以放到脚本代码中。通过暴露一个 options 对象即可。

export let options = {
  vus: 10,
  duration: "30s"
};

为了更为真实的模拟用户访问的场景,k6 提供了在整个测试期间让用户数量和访问时间呈阶段性变化的能力。只需要在 options 中增加 stages 参数即可:

export let options = {
 stages: [
    { duration: "30s", target: 20 },
    { duration: "1m30s", target: 10  },
    { duration: "20s", target: 0 },
  ]
};

在测试过程中需要检查网络请求是否成功,返回的状态码是否正确,以及响应时间是否符合某个阈值。在脚本中可以通过调用 check() 方法编写检查语句,以便 k6 能收集到报告。

import http from "k6/http";
import { check, sleep } from "k6";

export let options = {
  vus: 10,
  duration: "30s"
};

export default function() {
  let res = http.get("http://test.loadimpact.com");
  check(res, {
    "status was 200": (r) => r.status == 200,
    "transaction time OK": (r) => r.timings.duration < 200
  });
  sleep(1);
};

报告输出

k6 默认将报告输出到 stdout 控制台,同时也提供了多种格式报告输出,包括:

  • JSON
  • CSV
  • InfluxDB
  • Apache Kafka
  • StatsD
  • Datadog
  • Load Impact cloud platform

当然,我们在编写测试的时候不可能只有一个用例,对多个场景可以在脚本中通过 group 进行分组,分组后输出的报告会按照分组排列。同时,也可以使用对一个组整体性能衡量的指标 group_duration

import { group } from "k6";

export default function() {
  group("user flow: returning user", function() {
    group("visit homepage", function() {
      // load homepage resources
    });
    group("login", function() {
      // perform login
    });
  });
};

InfluxDB 等外部数据收集平台时,还可以打上标签,供过滤和检索使用。k6 提供了一些内置的标签,并允许用户自定义标签。

相关资料

  • 官方文档 https://docs.k6.io/docs
Last Updated:
Contributors: lin