k6 test 測試

K6 基本介紹、安裝及實作

邱祈竣 2023/04/27 15:10:47
4600

k6 在 2016 年加入開源的行列,並在 2021 年加入 Grafana Lab 。是用 Go 語言編寫的一種高效能的負載測試工具。 k6 沒有 GUI,不過能使用 JavaScript 來撰寫腳本,並提供許多範例testing API 。

整合工具

k6 也整合了許多平台及工具,並且支援了一般常見的協定,如 HTTP、WebSocket、gRPC 等。在輸出測試報表或是串接 CI 實現自動化測試,k6 都有很完整的生態圈可以提供整合。

程式效能

k6 的單個實例可以同時執行 30,000-40,000 個虛擬使用者( VUs )。 在某些情況下,此數量的VU最多可以生成300,000 HTTP 每秒請求 ( RPS )。


安裝 k6

k6 提供多種安裝方式,可以在 Linux, Mac, Windows 及 Docker 上安裝,以下介紹 Mac 及 Windows 兩種

MacOS:使用Homebrew

$ brew install k6

Windows:

使用chocolatey

$ choco install k6

 

或是官方下載安裝檔

 

安裝完成後可以使用 k6 version 確認版本

$ k6 version

執行 k6

首先,建立一個 k6-sample 並新增一個 script.js

$ mkdir k6-sample
$ cd k6-sample

建立一個簡單的情境:每一秒打一次
http://test.k6.io
import http from 'k6/http';
import { sleep } from 'k6';

export default function () { //default函式是每次執行都會做的動作,會反覆執行,HTTP請求要放在其中
  http.get('https://test.k6.io');
  sleep(1);
}

在 CLI 執行 k6 run {file_path}
$ k6 run script.js

執行結果:

scenarios:測試情境的參數 。說明這次宣告 1 個 VU(虛擬使用者)執行 1 次測試案例。
其他的各項參數 (METRIC NAME) 是測試結果的輸出指標,可以參考下方表格或是官方的 metrics

METRIC NAME TYPE DESCRIPTION
vus Gauge 當前活躍虛擬使用者數
vus_max Gauge 最大可能的虛擬用戶數(VU 資源已預先分配,確保在擴展負載級別時不會影響性能)
iterations Counter 該腳本執行一次所花費的時間
iteration_duration Trend 完成一次完整迭代所花費的時間,包括設置和拆卸所花費的時間
dropped_iterations Counter 由於缺少 VU或時間不足而未啟動的迭代次數。

data_received Counter 接收到的數據量
data_sent Counter 發送的數據量
checks Rate 檢查成功率
http_reqs Counter 計算測試總共發了多少 request
http_req_blocked Trend 發起請求之前阻塞(等待空閒 TCP)所花費的時間
http_req_connecting Trend 建立與 server 的 TCP 連接所花費的時間
http_req_tls_handshaking Trend 與 server 握手 TLS 所花費的時間
http_req_sending Trend API 發送到 server 所花費的時間
http_req_waiting Trend API 從 server 等待回應所花費的時間
http_req_receiving Trend API 從 server 回來所花費的時間
http_req_duration Trend API 請求的總時間。它等於 http_req_sending + http_req_waiting + http_req_receiving(即遠程服務器處理請求和響應需要多長時間,沒有初始 DNS 查找/連接時間)
http_req_failed Rate API 失敗的機率(預設 status code 是 200)

自訂參數 options

自訂參數可以直接在 cmd 指令輸入或是在程式碼上加入 options ,填入後 k6 便會依照參數執行。
可用參數可以參考官方文件

例如:要求 k6 模擬 10 個使用者連續執行該API 15 次。
可以在 cmd 加上以下參數 vus 及 interations

$ k6 run script.js --vus 10 --iterations 15
或是在程式加上 options

export const options = {
  vus: 10,        //模擬使用者數量
  iterations: 15  //模擬執行次數
};

如下圖

執行 script.js 後可以發現 k6 的確模擬了 10 個使用者並執行呼叫 API 15 次


k6 的生命週期

k6 的生命週期分為 init、setup、VU code、treadown,若是在執行測試前後有一些特殊需求,可以在 setup 函式與 teardown 函式上添加需要執行的事項

測試階段 目的 範例 執行次數
1. init 載入檔案、導入模塊、聲明生命週期函數 打開 JSON 文件,導入 模組 每個虛擬使用者 (VU) 都會執行
2. Setup 建立處理數據,VU 間共享數據 呼叫 API 啟動測試環境 執行一次
3. VU code 執行測試函數 發出 https 請求,驗證 response 每次迭代都會執行
4. Teardown 設置代碼的處理結果,停止測試環境 檢核設定是否有特定結果 執行一次

例如:在執行前先取得 API 資料,執行後印出 log,完成後再印出另一個 log

import http from 'k6/http';

export function setup() {
  const res = http.get('https://example.com/message');
  return { data: res.json() };
}

export function teardown(data) {
  console.log("EDED94神奇");
}

export default function (data) {
  console.log(JSON.stringify(data));
}

從下圖的執行成果,可以看到 INFO[0000] 將取得的 API 的資料透過 console.log 印出

透過上面的自訂參數與生命週期函式,我們可以自行組合需要的測試條件
例如:模擬使用者隨時間變化改變,並在測試完成後下一個 log

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

export let options = {
  stages: [                           // stages 可以模擬使用者持續增加或遞減
    { duration: '20s', target: 20 },  // 使用者在 20 秒內增加到 20 人
    { duration: '30s', target: 10 },  // 30秒內降至 10 人
    { duration: '10s', target: 0 },   // 最後 10 秒逐漸降 0 人
  ],
};

export function teardown() {         // 在 default 執行完後顯示 console.log
  console.log("EDED94神奇");
}

export default function () {
  let res = http.get('https://example.com/message');

  /**
   * check 類似斷言功能,但不會真的中斷執行,只是會返回 check 的數據百分比
   * 在這邊確認回傳狀態是 200,如果有非 200 的狀態會在結束後統一顯示結果
   */
  check(res, { 'status was 200': (r) => r.status == 200 });
  sleep(1);
}

心得

使用 k6 意外的簡單。安裝上不需要繁瑣的設定,官方文件清晰明了並附上了程式碼範例,讓人可以立刻使用。生態圈也有跟常用的 Swagger 整合,對新手來說非常的友善。

參考

k6
https://clouding.city/tool/k6/
https://www.tpisoftware.com/tpu/articleDetails/1597
https://blog.darkthread.net/blog/k6-load-testing/

邱祈竣