k6如何在默认函数外打开文件?CSV图片上传施压遇阻求助
解决k6中CSV批量上传图片的施压问题
方案1:Init阶段预加载所有文件内容
在init阶段一次性读取CSV和所有图片的二进制内容,存储到共享数组中,VU阶段直接从数组取数据上传。注意:若单张图片体积大、总数量多,可能引发内存溢出,适合单文件较小的场景。
import http from 'k6/http'; import { SharedArray } from 'k6/data'; import { check } from 'k6'; // Init阶段读取CSV与所有图片内容 const imageData = new SharedArray('image dataset', function () { const csvData = open('./image_list.csv').split('\n').slice(1); // 跳过表头 const result = []; for (const line of csvData) { if (!line.trim()) continue; const [filename, filesize, filepath, filehash] = line.split(','); // 读取文件二进制内容 const fileContent = open(filepath, 'b'); result.push({ filename, fileContent, filehash }); } return result; }); export const options = { vus: 10, duration: '30s', }; export default function () { // 随机选取预加载的图片数据 const item = imageData[Math.floor(Math.random() * imageData.length)]; // 构造上传表单 const formData = { file: http.file(item.fileContent, item.filename), filehash: item.filehash, }; // 发送上传请求 const res = http.post('https://your-upload-api.com/upload', formData); check(res, { '上传成功': (r) => r.status === 200, }); }
方案2:预编码图片为Base64存入CSV
提前将图片转为Base64编码并追加到CSV新列中,init阶段读取Base64字符串,VU阶段解码后上传。这种方式能降低init阶段的内存占用压力。
前置步骤:
- 用脚本批量将图片转为Base64,更新CSV新增
base64_content列 - 确保CSV中每行包含
filename,filesize,filepath,filehash,base64_content字段
import http from 'k6/http'; import { SharedArray } from 'k6/data'; import { check } from 'k6'; const imageData = new SharedArray('image dataset', function () { const csvData = open('./image_list_with_base64.csv').split('\n').slice(1); const result = []; for (const line of csvData) { if (!line.trim()) continue; const [filename, filesize, filepath, filehash, base64Content] = line.split(','); result.push({ filename, base64Content, filehash }); } return result; }); export const options = { vus: 10, duration: '30s', }; export default function () { const item = imageData[Math.floor(Math.random() * imageData.length)]; // 解码Base64为二进制内容 const fileContent = atob(item.base64Content); const formData = { file: http.file(fileContent, item.filename), filehash: item.filehash, }; const res = http.post('https://your-upload-api.com/upload', formData); check(res, { '上传成功': (r) => r.status === 200, }); }
方案3:自定义编译k6扩展(xk6-file)
使用xk6-file扩展突破VU阶段不能打开文件的限制,需要自行编译带该扩展的k6版本。
编译步骤:
- 安装xk6工具:
go install go.k6.io/xk6/cmd/xk6@latest - 编译带xk6-file的k6:
xk6 build --with github.com/avitalique/xk6-file@latest - 使用编译后的k6执行测试脚本
import http from 'k6/http'; import { SharedArray } from 'k6/data'; import { check } from 'k6'; import { open } from 'k6/x/file'; // 引入扩展的文件读取方法 const imagePaths = new SharedArray('image paths', function () { const csvData = open('./image_list.csv').split('\n').slice(1); const result = []; for (const line of csvData) { if (!line.trim()) continue; const [filename, filesize, filepath, filehash] = line.split(','); result.push({ filename, filepath, filehash }); } return result; }); export const options = { vus: 10, duration: '30s', }; export default function () { const item = imagePaths[Math.floor(Math.random() * imagePaths.length)]; // VU阶段直接打开文件读取内容 const fileContent = open(item.filepath, 'b'); const formData = { file: http.file(fileContent, item.filename), filehash: item.filehash, }; const res = http.post('https://your-upload-api.com/upload', formData); check(res, { '上传成功': (r) => r.status === 200, }); }
方案4:分批次分布式测试
若5000张图片总内存占用过高,可将CSV拆分为多个小文件(如每个1000行),启动多个k6实例分别加载不同的CSV分片,同时运行施压。这种方式避免单实例内存过载,适合大规模测试场景。
内容的提问来源于stack exchange,提问作者pkhauzhal
相关产品推荐
相关产品推荐

