如何将K6 Tool中default函数修改的数据传递到teardown阶段
K6 测试数据跨阶段传递解决方案
问题根因
K6 生命周期函数的设计逻辑决定了默认无法将 default 阶段对 data 的修改同步到 teardown 阶段:
setup()仅在测试启动时执行1次,返回的数据会作为只读副本分发给每个 VU 的default()函数- 每个 VU 在
default()中修改的都是自己本地的 data 副本,修改既不会同步给其他 VU,也不会回写到全局的teardown入参中 teardown()拿到的入参永远是setup()最初返回的原始值
可行实现方案
方案1:单VU场景使用顶层全局变量存储
如果测试仅使用1个VU,直接把需要共享的数据定义在顶层作用域即可,无需依赖 setup 的返回值:
import http from "k6/http"; import { group, check, sleep, fail } from "k6"; import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js'; import { textSummary } from "https://jslib.k6.io/k6-summary/0.0.1/index.js'; const SLEEP_DURATION = 1; var csvData = [{"Id":"P976O6RP8NSFN076RKLBSGK1Q8NZT7WA"},{"Id":"D4YJZFQJUPJTZWPLP2VB5M839SZBNNSO"}]; // 定义顶层变量存储共享数据 let sharedData = []; function removeId(arr, value) { arr = arr.filter(function(item) { return item.Id !== value }); return arr; } export function setup() { sharedData = JSON.parse(JSON.stringify(csvData)); } export default function() { let Id = csvData[0].Id; sharedData = removeId(sharedData, Id); console.log('ID deleted is: '+Id+' \nJson<data> in default :: '+JSON.stringify(sharedData)); } export function handleSummary(data) { return {}; } export function teardown() { console.log('\nJson<data> in teardown :: '+JSON.stringify(sharedData)); }
注意:多 VU 场景下每个 VU 会有独立的顶层变量副本,该方案不适用。
方案2:多VU场景只读共享使用SharedArray
如果仅需要所有 VU 共享同一份初始测试数据,不需要做修改,使用 K6 内置的 SharedArray 即可:
import { SharedArray } from 'k6/data'; // 仅初始化一次,所有VU共享同一份只读数据 const sharedCsvData = new SharedArray('test data', function () { return [{"Id":"P976O6RP8NSFN076RKLBSGK1Q8NZT7WA"},{"Id":"D4YJZFQJUPJTZWPLP2VB5M839SZBNNSO"}]; });
方案3:多VU场景需修改共享数据使用外部存储中转
如果需要多 VU 动态修改测试数据、且修改结果要在 teardown 阶段可见,使用外部 KV 存储中转即可,比如本地部署的 Redis,自行封装简单的 HTTP 接口操作即可:
import http from "k6/http"; // 自行实现对应HTTP接口操作外部存储 const STORAGE_URL = "http://127.0.0.1:8080"; export function setup() { const initData = JSON.parse(JSON.stringify(csvData)); http.post(`${STORAGE_URL}/set`, JSON.stringify({ key: "shared_test_data", value: initData }), { headers: {"Content-Type": "application/json"} }); } export default function() { // 读取最新数据 let currentData = http.get(`${STORAGE_URL}/get?key=shared_test_data`).json(); // 修改数据 let Id = csvData[0].Id; currentData = removeId(currentData, Id); // 写回存储 http.post(`${STORAGE_URL}/set`, JSON.stringify({ key: "shared_test_data", value: currentData }), { headers: {"Content-Type": "application/json"} }); } export function teardown() { // 读取最终修改结果 const finalData = http.get(`${STORAGE_URL}/get?key=shared_test_data`).json(); console.log('\nJson<data> in teardown :: '+JSON.stringify(finalData)); }
注意:多 VU 并发修改共享数据时需要自行处理并发锁,避免出现数据覆盖问题。
内容的提问来源于stack exchange,提问作者Chaitanya P
相关产品推荐
相关产品推荐

